惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
T
Threatpost
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
The Cloudflare Blog
博客园 - 聂微东
MyScale Blog
MyScale Blog
M
MIT News - Artificial intelligence
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Project Zero
Project Zero
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
Spread Privacy
Spread Privacy
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
S
Securelist
Schneier on Security
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
博客园 - 叶小钗
量子位
I
InfoQ
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
博客园_首页
C
CERT Recently Published Vulnerability Notes
I
Intezer
Y
Y Combinator Blog
T
Tailwind CSS Blog
Microsoft Security Blog
Microsoft Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
About on SuperTechFans
A
Arctic Wolf
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
PCI Perspectives
PCI Perspectives
The Last Watchdog
The Last Watchdog
月光博客
月光博客

囧克斯

奔四了,写给40岁的自己 有序退网 我和 Vue.js 的十年 我参与《代码之外 Beyond Code》的故事 博客站迁移至 VitePress 的备忘 写给我的奶奶 中文格式化小工具 zhlint 及其开发心得 vue-mark-display:用 markdown 语法轻松撰写幻灯片 我对技术会议的一些看法 VueConf Hangzhou 见闻 第四届 CSSConf CN 见闻 [译]Web 表单的未来 [译]苹果正在做一些他们的程序员明摆着不想要的东西 [译]为什么我不会无偿加班且你也不应该 [译]如果管理是唯一可走的路,那就完蛋了 [译]如何撰写 Git 提交信息 [译]C 程序的原则 Vue 2.0 来了! Weex 近 4 个月的开源之路 Weex 在 JS Runtime 内的多实例管理 我理解的 SPA 我理解的 Flux 架构 【整理】Vue 2.0 自 beta 1 到 beta 4 以来的主要更新 通过一张图走进 Vue 2.0 Code Review for Vue 2.0 Preview Vue 2.0 发布啦! 务实的小而美 Vue.js 1.0.0 发布了! [译]如何成为一名卓越的前端工程师 手机淘宝前端的图片相关工作流程梳理 [译]如何让办公室政治最小化 Vue.js 源码学习笔记 从原型到发布——“团队时间线” 1.0 开发心得 Vue + webpack 项目实践 用 Koa 写服务体验 webcomponents 笔记 之 配置管理 小秀个人的13~14年摄影作品 (共19张) 由今年D2前端论坛想到的 [译]CSS命名神马的真心难 [译]Git 分支的最佳实践 [译]撰写可测试的 JavaScript [译]语义化版本管理 [译]通过HTML5 Canvas API调节图像的亮度和颜色 [译]JavaScript V8性能小贴士 [译]视觉差,走起! [译]Chrome开发者工具中评估性能的五大新特性 精气神儿 细节无微不至,彩屏让人又爱又恨——新老“神机”大对决:Nokia 1050 vs Nokia 1202 秦升拿到红牌之后…… 用Sass重新整理自己的博客主题样式 Connect中间件使用手册 巧用 RequireJS Optimizer 给传统的前端项目打包 编辑器小调查结果 [译]JSLint 文档 烟火——写给蛇年的傲游和我 小秀个人的全年摄影作品 (共15张) 2012年终毫无正能量的总结 标签?ID?还是CLASS? 微创新=伪创新 HTML5峰会归来 分享bookmarklet一则:随意阅读 国际羽联和中国队之间的恶性循环 ZeroClipboard 学习笔记 “思考人生” 听杨东杰弹吉他 学习精髓 网站装修笔记20120426 网站装修笔记20120414 网站装修笔记20120406 分享Typecho插件:百度统计助手 我的得奖感言 网站装修笔记20120331 用CSS3制作尖角标签按钮样式 分享Typecho插件:Markdown 解析器 + 编辑器 分享Typecho皮肤:我的字很大 汇总自己过去的一些HTML5科普文章 html5中的消息通信简介 + 我的新网站开张 网站装修计划 Typed Arrays 是神马? 文明看球 HTML5中的文件处理 之 File Writer API HTML5中的文件处理 之 File API 独生子女、互相等和不耐烦 IndexedDB技术简介(四) IndexedDB技术简介(二) IndexedDB技术简介(一) 把博客的字体进一步调大,同时去掉了侧边栏 “模仿别人是为了找到自己” 写给我未婚妻的2011年 写给自己的2011年 手把手教你入门EaselJS做HTML5动画 “吃了吧,不吃就浪费了” 写给傲游的2011年 所谓专业 写给HTML5的2011年 对HTML5中LocalStorage的一些使用建议 回味一下我2011年看到的最过瘾的5场足球比赛 浅浅浅谈开饭店被顾客吃出“异物”的用户体验 前端的本职 继续对Mac穷追猛打 之 修改原生按钮文字大小的技巧
IndexedDB技术简介(三)
勾三股四 · 2012-02-13 · via 囧克斯

本文摘自 勾三股四 更早时期的 不老歌 博客。


今天做一个IndexedDB(以下简称IDB)的demo,运行环境是Firefox 10。

DEMO演示链接 (firefox 10+ only)

我们做一个阅读列表的页面,可以让用户把任意网址存入这个阅读列表中,并为每一个网址起一个名字,也可以随时删除,且列表可以按网址自动去重。

正如上一篇文章介绍的步骤,我们先初始化数据库,然后建表,然后把添加/删除/读取网址的事件和数据库操作绑定在一起。

首先是html代码:

<body onload="<strong>init()</strong>">
    _button onclick="<strong>clickAddBtn()</strong>">Add_/button>
    _ul <strong>id="list"</strong>>_/ul>
</body>

为了演示方便,我们引入jQuery作界面处理,再声明一个全局变量db,作为数据库连接的句柄;再声明一个全局变量list,作为网页中列表元素的jQuery句柄。

var db;
var list = $('#list');

然后定义数据库初始化的行数init

function init() {
    var req = window.<strong>mozIndexedDB</strong>.open('readinglist', '1.0');
    req.onsuccess = function (e) {
        <strong>db = this.result;</strong>
        // TODO: 连接成功后展示列表
    };
    req.onupgradeneeded = function (e) {
        <strong>db = this.result;</strong>
        // TODO: 版本不同时创建一个新的object store
    };
}

这段代码的作用是初始化数据库(readinglist)连接,并在第一次连接数据库时创建表(links)。我们把展示列表的函数定义为showList(),把创建表的代码也补充完整,即:

function init() {
    var req = window.mozIndexedDB.open('readinglist', '1.0');
    req.onsuccess = function (e) {
        db = this.result;
        <strong>showList();</strong>
    };
    req.onupgradeneeded = function (e) {
        db = this.result;
        <strong>db.createObjectStore('links', {keyPath: 'url'});</strong>
    };
}

然后我们定义添加/删除/展示链接的函数:add(title, url)/remove(url)/showList()

function add(<strong>title, url</strong>) {
    var <strong>link</strong> = {
        title: title,
        url: url
    }; // 创建要存储的对象
    var transaction = db.transaction('links', IDBTransaction.READ_WRITE);
    var store = transaction.objectStore('links');
    <strong>var req = store.put(link);</strong> // put的作用是key存在时做更新处理,不存在是做添加处理
    <strong>req.onsuccess = showList;</strong> // 添加成功后重新展示列表
}

function remove(<strong>url</strong>) {
    var transaction = db.transaction('links', IDBTransaction.READ_WRITE);
    var store = transaction.objectStore('links');
    <strong>var req = store.delete(url);</strong> // 删除此链接
    <strong>req.onsuccess = showList;</strong> // 删除成功后重新展示列表
}

function showList() {
    // TODO: clear element: #list

    var transaction = db.transaction('links');
    var store = transaction.objectStore('links');
    <strong>var range = IDBKeyRange.lowerBound(0);</strong> // 创建关键字范围描述
    <strong>var req = store.openCursor(range);</strong> // 创建在上述范围内遍历的游标
    req.onsuccess = function (e) {
        var result = this.result;
        if (result) {
            var link = result.value;
            // TODO: append this link to element: #list
            <strong>result.continue();</strong>
        }
    };
}

注意这里的IDBKeyRangestore.openCursor是用来遍历列表的,前者确定遍历的范围,后者根据前者的范围逐条触发onsuccess事件,这里定义的遍历范围是大于0,即所有非空的url,其实所有js类型的值都是可以在一起比大小的,如果想测试比较任意两个key的大小,可以运行函数window.mozIndexedDB.cmp(any first, any second)

最后,我们把最后两个TODO的部分补充完整,再把界面上的事件绑定好。编码工作就完成了。

function showList() {
    <strong>list.empty();</strong>

    var transaction = db.transaction('links');
    var store = transaction.objectStore('links');
    var range = IDBKeyRange.lowerBound(0); // 创建关键字范围描述
    var req = store.openCursor(range); // 创建在上述范围内遍历的游标
    req.onsuccess = function (e) {
        var result = this.result;
        if (result) {
            var link = result.value;
            <strong>appendLink(link);</strong>
            result.continue();
        }
    };
}

function appendLink(link) {
    var url = link.url;
    var title = link.title;
    var li = $('_li>_a href="#" target="_blank">_/a> _button>X_/button>_/li>');
    li.find('a').attr('title', title).attr('href', url).text(title);
    li.find('button').click(function (e) {
        <strong>remove(link.url);</strong>
    });
    list.append(li);
}

function clickAddBtn(e) {
    var title = prompt('please input the title') || '[No title]';
    var url = prompt('please input the url', 'http://');
    if (title && url) {
        <strong>add(title, url);</strong>
    }
}

DEMO演示链接 (firefox 10+ only)

下一篇讨论webkit下使用IDB的注意事项,并提供兼容问题的解决办法。

(未完待续)