2

IndexedDB技术简介(三)

 9 months ago
source link: https://jiongks.name/blog/2012-02-13
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

IndexedDB技术简介(三)

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


今天做一个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的注意事项,并提供兼容问题的解决办法。

(未完待续)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK