当前位置: 首页 > news >正文

网站页面开发流程重庆网站建设的意义

网站页面开发流程,重庆网站建设的意义,做网站好一点的软件,做暧暖ox免费网站IndexedDB_Web 离线数据库 本文会从头剖析一下 IndexedDB 在前端里面的应用的发展。 indexedDB 目前在前端慢慢得到普及和应用。它正朝着前端离线数据库技术的步伐前进。以前一开始是 manifest、localStorage、cookie 再到 webSQL#xff0c;现在 indexedDB 逐渐被各大浏览器认…IndexedDB_Web 离线数据库 本文会从头剖析一下 IndexedDB 在前端里面的应用的发展。 indexedDB 目前在前端慢慢得到普及和应用。它正朝着前端离线数据库技术的步伐前进。以前一开始是 manifest、localStorage、cookie 再到 webSQL现在 indexedDB 逐渐被各大浏览器认可。我们也可以针对它来进行技术上创新的开发。比如现在小视频非常流行那么我们可以在用户观看时通过 cacheStorage 缓存然后利用 WebRTC 技术实现 P2P 分发的控制不过需要注意一定要合理利用大小不然后果真的很严重。 indexedDB 的整体架构是由一系列单独的概念串联而成全部概念如下列表。一眼看去会发现没有任何逻辑不过这里我顺手画了一幅逻辑图中间会根据 函数 的调用而相互串联起来 IDBRequestIDBFactoryIDBDatabaseIDBObjectStoreIDBIndexIDBKeyRangeIDBCursorIDBTransaction 整体逻辑图如下 本文讲解流程 下文主要介绍了 indexedDB 的基本概念以及在实际应用中的实操代码。 indexedDB 基础概念。在 indexedDB 里面会根据索引 index 来进行整体数据结构的划分。indexedDB 数据库的更新是一个非常蛋疼的事情因为Web 的灵活性你既需要做好向上版本的更新也需要完善向下版本的容错性。indexedDB 高效索引机制在内部indexedDB 已经提供了 index、cursor等高效的索引机制推荐不要直接将所有数据都取回来再进行筛选而是直接利用 cursor 进行。最后推荐几个常用库 离线存储 IndexedDB 可以存储非常多的数据比如 Object,files,blobs 等里面的存储结构是根据 Database 来进行存储的。每个 DB 里面可以有不同的 object stores。具体结构如下图 并且我们可以给 key 设定相关特定的值然后在索引的时候可以直接通过 key 得到具体的内容。使用 IndexDB 需要注意其遵循的是同域原则。 indexDB 基本概念 在 indexDB 中有几个基本的操作对象 Database: 通过 open 方法直接打开可以得到一个实例的 DB。每个页面可以创建多个 DB不过一般都是一个。 idb.open(name, version, upgradeCallback) Object store: 这个就是 DB 里面具体存储的对象。这个可以对应于 SQL 里面的 table 内容。其存储的结构为 index: 有点类似于外链它本身是一种 Object store主要是用来在本体的 store 中索引另外 object store 里面的数据。需要区别的是key 和 index 是不一样的。可以参考 index DEMOmdn index。如下图表示 如下 code 为 // 创建 index var myIndex objectStore.index(lName); transaction: 事务其实就是一系列 CRUD 的集合内容。如果其中一个环节失败了那么整个事务的处理都会被取消。例如 var trans1 db.transaction(foo, readwrite); var trans2 db.transaction(foo, readwrite); var objectStore2 trans2.objectStore(foo) var objectStore1 trans1.objectStore(foo) objectStore2.put(2, key); objectStore1.put(1, key);cursor: 主要是用来遍历 DB 里面的数据内容。主要是通过 openCursor 来进行控制。 function displayData() {var transaction db.transaction([rushAlbumList], readonly);var objectStore transaction.objectStore(rushAlbumList);objectStore.openCursor().onsuccess function(event) {var cursor event.target.result;if(cursor) {var listItem document.createElement(li);listItem.innerHTML cursor.value.albumTitle , cursor.value.year;list.appendChild(listItem); cursor.continue();} else {console.log(Entries all displayed.);}}; }如何使用 IndexDB 上面说了几个基本的概念。那接下来我们实践一下 IndexDB。实际上入门 IndexDB 就是做几个基本的内容 打开数据库表设置指定的 primary Key定义好索引的 index 前期搭建一个 IndexedDB 很简单的代码如下 var request indexedDB.open(dbName, 2);request.onerror function(event) {// 错误处理程序在这里。 }; request.onupgradeneeded function(event) {var db event.target.result;// 设置 id 为 primaryKey 参数var objectStore db.createObjectStore(customers, { keyPath: id,{autoIncrement:true} });// 设置指定索引并确保唯一性objectStore.createIndex(name, name, { unique: false });objectStore.createIndex(email, email, { unique: true });}; 上面主要做了 3 件事 打开数据库表新建 Store并设置 primary Key设置 index 打开数据库表主要就是版本号和名字没有太多讲的我们直接从创建 store 开始吧。 创建 Object Store 使用的方法就是 IDBDatabase 上的 createObjectStore 方法。 var objectStore db.createObjectStore(customers, { keyPath: id,{autoIncrement:true} }); 基本函数构造为 IDBObjectStore createObjectStore(DOMString name,optional IDBObjectStoreParameters options)dictionary IDBObjectStoreParameters {(DOMString or sequenceDOMString)? keyPath null;boolean autoIncrement false; };keyPath: 用来设置主键的 key具体区别可以参考下面的 keyPath 和 generator 的区别。autoIncrement: 是否使用自增 key 的特性。 设置索引 index 在完成 PK(Primary key) 创建完毕后为了更好的搜索性能我们还需要额外创建 index。这里可以直接使用 objectStore.createIndex(indexName, property, options); indexName: 设置当前 index 的名字property: 从存储数据中指明 index 所指的属性。 其中options 有三个选项 unique: 当前 key 是否能重复 (最常用)multiEntry: 设置当前的 property 为数组时会给数组里面每个元素都设置一个 index 值。 # 创建一个名字叫 titleIndex 的 index并且存储的 index 不能重复 DB.createIndex(titleIndex, title, {unique: false}); 具体可以参考MDN createIndex Prop 和 googleDeveloper Index。 增删数据 在 IndexedDB 里面进行数据的增删都需要在 transaction 中完成。而这个增删数据大家可以理解为一次 request相当于在一个 transaction 里面管理所有当前逻辑操作的 request。所以在正式开始进行数据操作之前还需要给大家简单介绍一些如果创建一个事务。 事务的创建 transaction API如下 [代码1]。在创建时你需要手动指定当前 transaction 是那种类型的操作基本的内容有 “readonly”只读“readwrite”读写“versionchange”这个不能手动指定会在 upgradeneeded 回调事件里面自动创建。它可以用来修改现有 object store 的结构数据比如 index 等。 你可以通过在数据库打开之后通过 IDBDataBase 上的 transaction 方法创建如 [代码2]。 [代码1][NewObject] IDBTransaction transaction((DOMString or sequenceDOMString) storeNames,optional IDBTransactionMode mode readonly);[代码2] var transaction db.transaction([customers], readwrite); var objectStore transaction.objectStore(customers); # 遍历存储数据 for (var i in customerData) {var request objectStore.add(customerData[i]);request.onsuccess function(event) {// success, done?}; } 事务在创建的时候不仅仅可以制定执行的模式还可以指定本次事务能够影响的 ObjectStore 范围具体细节就是在第一个 transaction 参数里面传入的是一个数据然后通过 objectStore() 方法打开多个 OS 进行操作如下 [代码3]。 [代码3] var tx db.transaction([books,person], readonly); var books tx.objectStore(books); var person tx.objectStore(person);操作数据 完成了事务的创建之后我们就可以正式的开始进行数据的交互操作了也就是写我们具体的业务逻辑。如下 [代码1]一个完整数据事务的操作。 [代码1] var tx db.transaction(books, readwrite); var store tx.objectStore(books);store.put({title: Quarry Memories, author: Fred, isbn: 123456}); store.put({title: Water Buffaloes, author: Fred, isbn: 234567}); store.put({title: Bedrock Nights, author: Barney, isbn: 345678});tx.oncomplete function() {// All requests have succeeded and the transaction has committed. }; 通过 objectStore 回调得到的 IDBObjectStore 对象我们就可以进行一些列的增删查改操作了。可以参考 [代码2]。详细的可以参考文末的 appendix。 [代码2][NewObject] IDBRequest put(any value, optional any key);[NewObject] IDBRequest add(any value, optional any key);[NewObject] IDBRequest delete(any query); 索引数据 索引数据是所有数据库里面最重要的一个。这里我们可以使用游标index 来做。例如通过 index 来快速索引 key 值参考 [代码1]。 [代码1] var index objectStore.index(name); index.get(Donna).onsuccess function(event) {alert(Donnas SSN is event.target.result.ssn); };更详细的内容可以参考下文 数据索引方式。 keyPath 和 key Generator 何谓 keyPath 和 keyGenerator 应该算是 IndexedDB 里面比较难以理解的概念。简单来说IndexedDB 在创建 Store 的时候必须保证里面的数据是唯一的那么得需要像其它数据库一样设置一个 primary Key 来区分不同数据。而 keyPath 和 Generator 就是两种不同的设置 key 的方式。 设置 keyPath # 设置预先需要存放的数据const customerData [{ ssn: 444-44-4444, name: Bill, age: 35, email: billcompany.com },{ ssn: 555-55-5555, name: Donna, age: 32, email: donnahome.org } ];# 通过 keyPath 设置 Primary Key var objectStore db.createObjectStore(customers, { keyPath: ssn }); 因为 ssn 在该数据集是唯一的所以我们可以利用它来作为 keyPath 保证 unique 的特性。或者可以设置为自增的键值比如 id 类似的。 upgradeDb.createObjectStore(logs, {keyPath: id, autoIncrement:true}); 使用 generator generator 会每次在添加数据时自动创建一个 unique value。这个 unique value 是和你的实际数据是分开的。里面直接通过 autoIncrement:true 来设置即可。 upgradeDb.createObjectStore(notes, {autoIncrement:true}); indexDB 打开注意事项 检查是否支持 indexDB if (!(indexedDB in window)) {console.log(This browser doesn\t support IndexedDB);return; } 版本更新: indexDB 在生成一个 indexDB 实例时需要手动指定一个版本号。而最常用的 idb.open(test-db7, 2, function(upgradeDb) {}) 这样会造成一个问题比如上线过程中用户A第一次请求返回了新版本的网页连接了版本2。之后又刷新网页命中了另一台未上线的机器连接了旧版本1 出错。主要原因是 indexedDB API 中不允许数据库中的数据仓库在同一版本中发生变化. 并且当前 DB 版本不能和低版本的 version 连接。 比如你一开始定义的 DB 版本内容为 # 版本一定义的内容 db.version(1).stores({friends: id,name});# 版本二修改结构为 db.version(2).stores({friends: id,name,shoeSize}); 如果此时用户先打开了 version(1)但是后面又得到的是 version(2) 版本的 HTML这时就会出现 error 的错误。 参考 - 版本更替 版本更新 这个在 IndexDB 是一个很重要的问题。主要原因在于 indexedDB API 中不允许数据库中的数据仓库在同一版本中发生变化. 并且当前 DB 版本不能和低版本的 version 连接。 上面就可以抽象为一个问题 你什么情况下需要更新 IndexDB 的版本呢? 该表数据库里面的 keyPath 时。你需要重新设计数据库表结构时比如新增 index # 版本 1 的 DB 设计有一个主键 id 和 index-name db .version(1) .stores({friends: id,name})# 如果直接想新增一个 key例如 male是无法成功的 db .version(1) .stores({friends: id,name,male})# 正确办法是直接修改版本号更新 db .version(2) .stores({friends: id,name,male}) 不过如果直接修改版本号会出现这样一个 case: 由于原始 HTML 更新问题用户首先访问的是版本 1 的 A 页面然后访问更新过后的 B 页面。这时IndexDB 成功更新为高版本。但是用户下次又命中了老版本的 A 页面此时 A 中还是连接低版本的 IndexDB ,就会报错导致你访问失败。 解决办法就是设置过滤在 open 的时候手动传入版本号 # 打开版本 1 的数据库 var dbPromise idb.open(db1, 1, function(upgradeDb){...})# 打开版本 2 的数据库 var dbPromise idb.open(db2, 2, function(upgradeDb){...}) 不过这样又会造成另外一个问题即数据迁移老版本数据不可能不要吧。这里IndexDB 会有一个 updateCallback 给你触发你可以直接在里面做相关的数据迁移处理。 var dbPromise idb.open(test-db7, 2, function(upgradeDb) {switch (upgradeDb.oldVersion) {case 0:upgradeDb.createObjectStore(store, {keyPath: name});case 1:var peopleStore upgradeDb.transaction.objectStore(store);peopleStore.createIndex(price, price);} }); 在使用的时候一定要注意 DB 版本的升级处理比如有这样一个 case你的版本已经是 3不过你需要处理版本二的数据: # 将版本二 中的 name 拆分为 firstName 和 lastName db.version(3).stores({friends: id,shoeSize,firstName,lastName}).upgrade(function(t) {return t.friends.toCollection().modify(function(friend) {// Modify each friend:friend.firstName friend.name.split( )[0];friend.lastName friend.name.split( )[1];delete friend.name;}); }); 对于存在版本 2 数据库的用户来说是 OK 的但是对于某些还没有访问过你数据库的用户来说这无疑就报错了。解决办法有 保留每个版本时创建的字段和 stores在更新 callback 里面对处理的数据判断是否存在即可 在 Dexie.js DB 数据库中需要你保留每次 DB 创建的方法实际上是通过 添加 swtich case 来完成每个版本的更新 # Dexie.js 保留 DB 数据库 db.version(1).stores({friends: id,name}); db.version(2).stores({friends: id,name,shoeSize}); db.version(3).stores({friends: id,shoeSize,firstName,lastName}).upgrade(...)# 内部原理直接添加 switch case 完成版本更新 var dbPromise idb.open(test-db7, 2, function(upgradeDb) {switch (upgradeDb.oldVersion) {case 0:upgradeDb.createObjectStore(store, {keyPath: name});case 1:var peopleStore upgradeDb.transaction.objectStore(store);peopleStore.createIndex(price, price);} }); 如果遇到一个页面打开但是另外一个页面拉取到新的代码进行更新时这个时候还需要将低版本 indexedDB 进行显式的关闭。具体操作办法就是监听 onversionchange 事件当版本升级时通知当前 DB 进行关闭然后在新的页面进行更新操作。 openReq.onupgradeneeded function(event) {// 所有其它数据库都已经被关掉了直接更新代码db.createObjectStore(/* ... */);db.onversionchange function(event) {db.close();};} 最后更新是还有几个注意事项 版本更新不能改变 primary key回退代码时千万注意版本是否已经更新。否则只能增量更新重新修改版本号来修复。 存储加密特性 有时候我们存储时想得到一个由一串 String 生成的 hash key那在 Web 上应该如何实现呢 这里可以直接利用 Web 上已经实现的 WebCrypto为了实现上述需求我们可以直接利用里面的 digest 方法即可。这里 MDN 上已经有现成的办法我们直接使用即可。 参考 WebCrypto 加密手段 存储上限值 基本限制为 浏览器限制Chrome可用空间 6%Firebox可用空间 10%Safari 50MBIE10 250MB 逐出策略为: 浏览器逐出政策Chrome在 Chrome 耗尽空间后采用 LRU 策略Firebox在整个磁盘已装满时采用 LRU 策略Safari无逐出IE10无逐出 参考 存储上限值 浏览器内核存储上限值处理 数据索引方式 在数据库中除了基本的 CRUD 外一个高效的索引架构则是里面的重中之重。在 indexedDB 中我们一共可以通过三种方式来索引数据 固定的 key 值索引外键index游标cursor 固定 key 索引 IDBObjectStore 提供给了我们直接通过 primaryKey 来索引数据参考 [代码1]这种方式需要我们一开始就知道目标的 key 内容。当然也可以通过 getAll 全部索引数据。 [代码1][NewObject] IDBRequest get(any query);[NewObject] IDBRequest getKey(any query);[NewObject] IDBRequest getAll(optional any query,optional [EnforceRange] unsigned long count);[NewObject] IDBRequest getAllKeys(optional any query,optional [EnforceRange] unsigned long count); 比如我们通过 primaryKey 得到一条具体的数据 db.transaction(customers).objectStore(customers).get(id_card_1118899).onsuccess function(event) {// data is event.target.result.name };也可以 fetch 整个 Object Store 的数据。这些场景用处比较少这里就不过多讲解。我们主要来了解一下 index 的索引方式。 index 索引 如果想要查询某个数据直接通过整个对象来进行遍历的话这样做性能耗时是非常大的。如果我们结合 index 来将 key 加以分类就可以很快速的实现指定数据的索引。这里我们可以直接利用 IDBObjectStore 上面的 index() 方法来获取指定 index 的值具体方法可以参考 [代码1]。 [代码1]IDBIndex index(DOMString name); 该方法会直接返回一个 IDBIndex 对象。这你也可以理解为一个类似 ObjectStore 的微型 index 数据内容。接着我们可以使用 get() 方法来获得指定 index 的数据参考[代码2]。 [代码2] var index objectStore.index(name); index.get(Donna).onsuccess function(event) {alert(Donnas SSN is event.target.result.ssn); }; 使用 get 方法不管你的 index 是否是 unique 的都会只会返回第一个数据。如果想得到多个数据的话可以使用 getAll(key) 来做。通过 getAll() 得到的回调函数直接通过 event.target.result 可以得到对应的 value 内容。 objectStore.getAll().onsuccess function(event) {printf(event.target.result); // Array}; 除了通过 getAll() 得到所有数据外还可以采用更高效的 cursor 方法遍历得到的数据。 参考 getAll() 和 openCursor 实例 游标索引 所谓的游标大家心里应该可以有一个初步的印象就像我们物理尺子上的那个东西可以自由的移动来标识指向的对象内容。cursor 里面有两个核心的方法 advance(count): 将当前游标位置向前移动 count 位置continue(key): 将当前游标位置移动到指定 key 的位置如果没提供 key 则代表的移动下一个位置。 比如我们使用 cursor 来遍历 Object Store 的具体数据。 objectStore.openCursor().onsuccess function(event) {var cursor event.target.result;if(cursor) {// cursor.key // cursor.valuecursor.continue();} else {console.log(Entries all displayed.);}}; 通常游标可以用来遍历两个类型的数据一个是 ObjectStore、一个是 Index。 Object.store: 如果在该对象上使用游标那么会根据 primaryKey 遍历整个数据注意这里不会存在重复的情况因为 primaryKey 是唯一的。index: 在 index 上使用游标的话会以当前的 index 来进行遍历其中可能会存在重复的现象。 在 IDBObjectStore 对象上有两种方法来打开游标 openCursor: 遍历的对象是 具体的数据值最常用的方法openKeyCursor: 遍历的对象是 数据 key 值 这里我们通过 openCursor 来直接打开一个 index 数据集然后进行遍历。 PersonIndex.openCursor().onsuccess function(event) {var cursor event.target.result;if (cursor) {customers.push(cursor.value);cursor.continue();}else {alert(Got all customers: customers);} }; 在游标中还提供给了一个 update 和 delete 方法我们可以用它来进行数据的更新操作否则的话就直接使用 ObjectStore 提供的 put 方法。 游标里面我们还可以限定其遍历的范围和方向。这个设置是我们直接在 openCursor() 方法里面传参完成的该方法的构造函数参考 [代码1]。他里面可以传入两个参数第一个用来指定范围第二个用来指定 cursor 移动的方向。 [代码1] IDBRequest openCursor(optional any query,optional IDBCursorDirection direction next);如果需要对 cursor 设置范围的话就需要使用到 IDBKeyRange 这个对象使用样板可以参考 [代码2]。IDBKeyRange 里面 key 参考的对象 因使用者的不同而不同。如果是针对 ObjectStore 的话则是针对 primaryKey如果是针对 Index 的话则是针对当前的 indexKey / 匹配所有在 “Bill” 前面的, 但是不需要包括 Bill var lowerBoundOpenKeyRange IDBKeyRange.lowerBound(Bill, true); 比如我们这里对 PersonIndex 设置一个 index 范围即索引 在 villainhr 和 jimmyVV 之间的数据集合。 # 都包括 villainhr 和 jimmyVV 的数据 var boundKeyRange IDBKeyRange.bound(villainhr, jimmyVV, true, true);PersonIndex.openCursor(boundKeyRange).onsuccess function(event) {var cursor event.target.result;if (cursor) {// Do something with the matches.cursor.continue();} }; 如果你还想设置遍历的方向和是否排除重复数据还可以根据 [代码2] 的枚举类型来设置。比如在 [代码3] 中我们改变默认的 cursor 遍历数据的方向为 prev从末尾开始。 [代码2] enum IDBCursorDirection {next,nextunique,prev,prevunique };[代码3] objectStore.openCursor(null, IDBCursor.prev).onsuccess function(event) {var cursor event.target.result;if (cursor) {// cursor.value cursor.continue();} }; 事务读取性能 在 indexDB 里面的读写全部是基于 transaction 模式来的。也就是 IDBDataBase 里面的 transaction 方法如下 [代码1]。所有的读写都可以比作在 transaction 作用域下的请求只有当所有请求完成之后该次 transaction 才会生效否则就会抛出异常或者错误。transaction 会根据监听 errorabort以及 complete 三个事件来完成整个事务的流程管理参考[代码2]。 [代码1][NewObject] IDBTransaction transaction((DOMString or sequenceDOMString) storeNames,optional IDBTransactionMode mode readonly);[代码2]attribute EventHandler onabort;attribute EventHandler oncomplete;attribute EventHandler onerror; 例如 var request db.transaction([customers], readwrite).objectStore(customers).delete(gg); request.onsuccess function(event) {// delete, done }; 你可以在 transaction 方法里面手动传入 readwrite 或者其他表示事务的 readonly 参数来表示本次事务你会进行如何的操作。IndexedDB 在初始设计时就已经决定了它的性能问题。 只含有 readonly 模式的 transaction 可以并发进行执行 含有 write 模式的 transaction 必须按照队列 来 执行 这就意味着如果你使用了 readwrite 模式的话那么后续不管是不是 readonly 都必须等待该次 transaction 完成才行。 常用技巧 生成 id 的主键 指定 primaryKey 生成时是通过 createObjectStore 方法来操作的。有时候我们会遇到想直接得到一个 key并且存在于当前数据集中可以在 options 中同时加上 keyPath 和 autoIncrement 属性。该 key 的范围是 [1- ]参考 keygenerator key 的大小 db.createObjectStore(table1, {keyPath: id, autoIncrement: true}); 推荐 阅读推荐 indexedDB W3C 文档 indexedDB 入门 MDN indexedDB 入门 好用库推荐 idb: 一个 promise 的 DB 库 Indexed Appendix IndexedDB 数据库使用key-value键值对储存数据.你可以对对象的某个属性创建索引index以实现快速查询和列举排序。.key可以使二进制对象IndexedDB 是事务模式的数据库. IndexedDB API提供了索引(indexes), 表(tables), 指针(cursors)等等, 但是所有这些必须是依赖于某种事务的。The IndexedDB API 基本上是异步的.IndexedDB 数据库的请求都会包含 onsuccess和onerror事件属性。IndexedDB 在结果准备好之后通过DOM事件通知用户IndexedDB是面向对象的。indexedDB不是用二维表来表示集合的关系型数据库。这一点非常重要将影响你设计和建立你的应用程序。indexedDB不使用结构化查询语言SQL。它通过索引(index)所产生的指针(cursor)来完成查询操作从而使你可以迭代遍历到结果集合。IndexedDB遵循同源same-origin策略 局限和移除 case 全球多种语言混合存储。国际化支持不好。需要自己处理。和服务器端数据库同步。你得自己写同步代码。全文搜索。 在以下情况下数据库可能被清除: 用户请求清除数据。浏览器处于隐私模式。最后退出浏览器的时候数据会被清除。硬盘等存储设备的容量到限。不正确的不完整的改变. 常规概念 数据库 数据库: 通常包含一个或多个 object stores. 每个数据库必须包含以下内容 名字(Name) 它标识了一个特定源中的数据库并且在数据库的整个生命周期内保持不变. 此名字可以为任意字符串值包括空字符串.当前版本(version). 当一个数据库首次创建时它的 version 为1除非另外指定. 每个数据库在任意时刻只能有一个 version对象存储(object store): 用来承载数据的一个分区.数据以键值对形式被对象存储永久持有。在 OS 中创建一个 key 可以使用 key generator 和 key path。 key generator: 简单来说就是在存储数据时主动生成一个 id 来区分每条记录。这种情况下 存储数据的 key 是和 value 分开进行存储的也就是 out of line。key path: 需要用户主动来设置储存数据的 key 内容request: 每次读写操作可以当做一次 request.transaction: 一系列读写请求的集合。index: 一个特殊的 Object Store用来索引另外一个 Store 的数据。具体数据 key/value key: 这个 key 的值可以通过三种方式生成。 a key generator, a key path, 用户指定的值。并且这个 key 在当前的 Object Store 是唯一的。一个 key 类型可以是 string, date, float, and array 类型。不过在老版本的时候一般只支持 string or integer。现在版本应该都 OK 了 key generator: 相当于以一种 id 的形式来生成一个 key 值。key path: 当前指定的 key 可以根据 value 里面的内容来指定。里面可以为一些分隔符。指定的 key这个就是需要用户手动来指定生成。value: 可以存储 boolean, number, string, date, object, array, regexp, undefined, and null。现在还可以存储 files and blob 对象。 操作作用域 scope这可以比作 transaction 的作用域即一系列 transaction 执行的顺序。该规定多个 reading transaction 能够同时执行。但是 writing 则只能排队进行。key range: 用来设置取出数据的 key 的范围内容。 参考 原生概念 IndexedDB IDBFactory 这其实就是 indexDB 上面挂载的对象。主要 API 如下 [Exposed(Window,Worker)] interface IDBFactory {[NewObject] IDBOpenDBRequest open(DOMString name,optional [EnforceRange] unsigned long long version);[NewObject] IDBOpenDBRequest deleteDatabase(DOMString name);short cmp(any first, any second); };你可以直接通过 open 来打开一个数据库。通过 返回一个 Request 对象来进行结果监听的回调 var request indexedDB.open(AddressBook, 15); request.onsuccess function(evt) {...}; request.onerror function(evt) {...}; 参考 IndexDB Factory API IDBRequest 当你通过 open 方法处理过后就会得到一个 Request 回调对象。这个就是 IDBRequest 的实例。 [Exposed(Window,Worker)] interface IDBRequest : EventTarget {readonly attribute any result; // 通过 open 打开过后的 IDBObjectStore 实例 readonly attribute DOMException? error;readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;readonly attribute IDBTransaction? transaction;readonly attribute IDBRequestReadyState readyState;// Event handlers:attribute EventHandler onsuccess;attribute EventHandler onerror; };enum IDBRequestReadyState {pending,done };[Exposed(Window,Worker)] interface IDBOpenDBRequest : IDBRequest {// Event handlers:attribute EventHandler onblocked;attribute EventHandler onupgradeneeded; }; 你可以通过 result 得到当前数据库操作的结果。如果你打开更新后的版本号的话还需要监听 onupgradeneeded 事件来实现。最常通过 indexedDB.open 遇见的错误就是 VER_ERR 版本错误。这表明存储在磁盘上的数据库的版本高于你试图打开的版本。 db.onerror function(event) {// Generic error handler for all errors targeted at this databases// requests!alert(Database error: event.target.errorCode); }; 所以一般在创建 IndexDB 时还需要管理它版本的更新操作这里就需要监听 onupgradeneeded 来是实现。 request.onupgradeneeded function(event) { // 更新对象存储空间和索引 .... }; 或者我们可以直接使用 idb 微型库来实现读取操作。 var dbPromise idb.open(test-db3, 1, function(upgradeDb) {if (!upgradeDb.objectStoreNames.contains(people)) {upgradeDb.createObjectStore(people, {keyPath: email});}if (!upgradeDb.objectStoreNames.contains(notes)) {upgradeDb.createObjectStore(notes, {autoIncrement: true});}if (!upgradeDb.objectStoreNames.contains(logs)) {upgradeDb.createObjectStore(logs, {keyPath: id, autoIncrement: true});}});其中通过 onupgradeneeded 回调得到的 event.result 就是 IDBDatabase 的实例常常用来设置 index 和插入数据。参考下面内容。 参考 IDBRequest API IDBDatabase 该对象常常用来做 Object Store 和 transaction 的创建和删除。该部分是 onupgradeneeded 事件获得的 event.target.result 对象 request.onupgradeneeded function(event) { // 更新对象存储空间和索引 .... // event.target.result 对象 }; 具体 API 内容如下 [Exposed(Window,Worker)] interface IDBDatabase : EventTarget {readonly attribute DOMString name;readonly attribute unsigned long long version;readonly attribute DOMStringList objectStoreNames;[NewObject] IDBTransaction transaction((DOMString or sequenceDOMString) storeNames,optional IDBTransactionMode mode readonly);void close();[NewObject] IDBObjectStore createObjectStore(DOMString name,optional IDBObjectStoreParameters options);void deleteObjectStore(DOMString name);// Event handlers:attribute EventHandler onabort;attribute EventHandler onclose;attribute EventHandler onerror;attribute EventHandler onversionchange; };dictionary IDBObjectStoreParameters {(DOMString or sequenceDOMString)? keyPath null;boolean autoIncrement false; }; 如果它通过 createObjectStore 方法那么得到的就是一个 IDBObjectStore 实例对象。如果是 transaction 方法那么就是 IDBTransaction 对象。 IDBObjectStore 该对象一般是用来创建 index 和插入数据使用。 可以参考 [Exposed(Window,Worker)] interface IDBObjectStore {attribute DOMString name;readonly attribute any keyPath;readonly attribute DOMStringList indexNames;[SameObject] readonly attribute IDBTransaction transaction;readonly attribute boolean autoIncrement;[NewObject] IDBRequest put(any value, optional any key);[NewObject] IDBRequest add(any value, optional any key);[NewObject] IDBRequest delete(any query);[NewObject] IDBRequest clear();[NewObject] IDBRequest get(any query);[NewObject] IDBRequest getKey(any query);[NewObject] IDBRequest getAll(optional any query,optional [EnforceRange] unsigned long count);[NewObject] IDBRequest getAllKeys(optional any query,optional [EnforceRange] unsigned long count);[NewObject] IDBRequest count(optional any query);[NewObject] IDBRequest openCursor(optional any query,optional IDBCursorDirection direction next);[NewObject] IDBRequest openKeyCursor(optional any query,optional IDBCursorDirection direction next);IDBIndex index(DOMString name);[NewObject] IDBIndex createIndex(DOMString name,(DOMString or sequenceDOMString) keyPath,optional IDBIndexParameters options);void deleteIndex(DOMString name); };dictionary IDBIndexParameters {boolean unique false;boolean multiEntry false; };IDBIndex 该对象是用来进行 Index 索引的操作对象里面也会存在 get 和 getAll 等方法。详细内容如下 [Exposed(Window,Worker)] interface IDBIndex {attribute DOMString name;[SameObject] readonly attribute IDBObjectStore objectStore;readonly attribute any keyPath;readonly attribute boolean multiEntry;readonly attribute boolean unique;[NewObject] IDBRequest get(any query);[NewObject] IDBRequest getKey(any query);[NewObject] IDBRequest getAll(optional any query,optional [EnforceRange] unsigned long count);[NewObject] IDBRequest getAllKeys(optional any query,optional [EnforceRange] unsigned long count);[NewObject] IDBRequest count(optional any query);[NewObject] IDBRequest openCursor(optional any query,optional IDBCursorDirection direction next);[NewObject] IDBRequest openKeyCursor(optional any query,optional IDBCursorDirection direction next); }; 参考 idb 开源库微型代码库 treo 开源库 dexie.js 开源库 indexeddb 原生概念 IndexedDB
http://www.pierceye.com/news/643770/

相关文章:

  • 优化网站要怎么做中国外协机械加工订单网
  • 运动健身型网站开发永久网站空间
  • 好的网站建设公司排名小程序怎么引流推广
  • 建设部网站 光纤到户平顶山 网站建设公司
  • 网站建设费计入哪个科目赛罕区城乡建设局网站
  • 计算机协会网站模板如何做微信下单小程序
  • 购物网站开发流程图大连装修公司
  • 网站开发定制推广杭州手表网站域名
  • 惠州网站建设方案推广企业网站必备模块
  • 网站内页产品做跳转做电商有哪些平台
  • 如何自建网站服务器wordpress下载权限
  • 重庆专业网站设计服务做染料的网站
  • 长春模板建站公司浙江住房和建设厅网站
  • 网站建设公司 佛山南京移动网站建设
  • 网站建设目录规范微信h5网站开发
  • 做ppt卖给网站枣庄做网站优化
  • 新乡营销型网站建设做软件的中介网站
  • 延边州建设局网站软件公司主要做哪些
  • 建设网站带后台管理程序制作软件
  • 榆林市住房和城市建设局网站梁志天设计公司项目
  • 建设网站怎么搞做非法网站判刑多少年
  • 做查询网站 发布数据wordpress nextapp
  • 福鼎建设局网站首页上海社区网站建设
  • 企业网站免费推广方案wordpress文章类模板
  • 从化区住房和建设局网站网站开发所需要的的环境
  • 深圳微商城网站制作联系电话国家信息网
  • 网站没有收录怎么办巴中城乡和住房建设厅网站
  • 做个网站要钱吗wordpress动漫网站模板
  • 高性能网站建设进阶指南下载wdcp 快速迁移网站
  • 建设教育协会网站房产资讯的网站怎么做