IndexedDB 存储快捷键配置的核心是:通过 indexedDB.open() 打开或新建名为 "keymapDB" 的数据库,在 onupgradeneeded 中创建 keyPath 为 "id" 的 "keymaps" 对象存储,并支持按 scope 建索引;所有增删改查操作必须在事务中使用 put()、get()、getAll() 等方法异步执行,主键推荐唯一组合键(如 "ctrl-shift-s"),版本升级需显式提高 DB_VERSION。

在 JavaScript 中用 IndexedDB 存储用户自定义快捷键配置,核心是创建数据库、定义对象存储(Object Store),然后增删改查快捷键数据。关键在于结构设计合理、操作异步安全、错误有兜底。
设计快捷键数据结构和数据库版本
快捷键通常包含触发键(如 Ctrl+Shift+S)、绑定动作(如 "saveDraft")、启用状态等。建议用唯一 ID 或组合键名(如 "ctrl-shift-s")作为主键,便于快速读写。
- 数据库名建议固定,如 "keymapDB";版本从 1 开始,后续结构变更时升级版本号
- 对象存储名推荐 "keymaps",启用 keyPath: "id" 或 autoIncrement: true(若用自增 ID)
- 若需按应用/场景分类快捷键,可加字段 scope: "editor" 或 category: "navigation"
打开数据库并初始化对象存储
使用 indexedDB.open() 打开或新建数据库,监听 onupgradeneeded 创建/更新表结构:
const DB_NAME = "keymapDB";
const DB_VERSION = 1;
const STORE_NAME = "keymaps";
const openDB = () => {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
// 主键用字符串 id,支持自定义键名
const store = db.createObjectStore(STORE_NAME, { keyPath: "id" });
// 可选:为 scope 或 isActive 建索引,方便筛选
store.createIndex("byScope", "scope", { unique: false });
}
};
});
};
保存、读取和更新快捷键配置
所有操作必须在事务中进行。写入用 put()(自动覆盖同 id 记录),读取用 get() 或 getAll():
立即学习“Java免费学习笔记(深入)”;
- 保存单条:传入对象如 { id: "ctrl-alt-t", action: "openToolbar", scope: "global", enabled: true }
- 批量保存:用 add() 或循环 put(),注意避免重复 id 冲突
- 读取全部:事务中调用 store.getAll();按 id 查:用 store.get("ctrl-shift-s")
- 启用/禁用开关:只需更新 enabled 字段后 put() 回库
处理兼容性与常见异常
IndexedDB 在 Safari 和旧版 Edge 中可能限制较多,需主动降级或提示:
- 检查全局 window.indexedDB 是否存在,不存在时 fallback 到 localStorage(仅临时方案)
- 事务失败(如用户禁用隐私模式)时,捕获 transaction.onabort 和 request.onerror
- 避免在页面卸载前未完成写入——可监听 beforeunload 并用 event.preventDefault() 阻止(谨慎使用)
- 首次加载配置时,建议加 loading 状态,并设超时兜底(如 2s 后默认空配置)
不复杂但容易忽略细节:主键设计要能唯一标识快捷键组合,事务生命周期要手动管理,错误不能静默吞掉。实际项目中封装成类或 hook(如 useKeymapDB)会更易维护。


















