05-解决方案
17.1.2 解决方案
我们将用一个简单的任务列表来说明客户端数据存储。和本章的许多秘诀一样,将使用一个jQuery插件处理浏览器的不一致性:
<!DOCTYPE html>
<html><head>
<title>17.1 - Using Client-Side Storage</title>
<script type="text/javascript" src="../../jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.jstore-all.js"></script>
</head>
<body>
<h1>17.1 - Using Client-Side Storage</h1>
<p>Storage engine: <span id="storage-engine"></span></p>
<input id="task-input"></input>
<input id="task-add" type="submit" value="Add task"></input>
<input id="list-clear" type="submit" value="Remove all tasks"></input>
<ul id="task-list"></ul>
</body></html>
HTML由操纵任务列表的表单元素组成:一个输入任务的文本字段,一个添加任务的按钮和一个删除所有任务的按钮。当前任务将用无序列表列出:
(function($) {
$.jStore.ready(function(ev,engine) {
engine.ready(function(ev,engine) {
$('#storage-engine').html($.jStore.CurrentEngine.type);
$('#task-list').append($.store('task-list'));
});
});
jStore插件提供两个回调方法: jStore.ready()
和 engine.ready()
。这两个方法和jQuery的 ready()
函数很类似,允许在jStore和当前存储引擎完成内部初始化后进行一些初始设置。这是在页面上显示当前使用的存储引擎和任何保存的任务列表项的一个机会:
$('document').ready(function() {
$('#task-add').click(function() {
var task = $('#task-input').val();
var taskHtml = '<li><a href="#">done</a> ' + task + '</li>';
$.store('task-list',$('#task-list').append(taskHtml).html());
return false;
});
一旦文档就绪,就为相关的控件绑定单击事件。当单击“Add task”(添加任务)按钮时,用任务文本字段的内容和标记该任务完成的一个链接构造列表项元素。然后,把该列表项附加到任务列表的内容中,任务列表用 tasklist
键码存储在本地存储器上。以后,该列表可以用这个键码读取,这一步在 engine.ready()
回调中完成:
$('#list-clear').click(function() {
$('#task-list').empty();
$.remove('task-list');
return false;
});
当单击“Remove all tasks”(删除所有任务) 时,包含任务列表的元素将清空。 task-list
键码及其相关的值从本地存储中删除。
$('#task-list a').live('click',function() {
$(this).parent().remove();
var taskList = $('#task-list').html();
if( taskList ) { $.store('task-list',taskList); }
else { $.remove('task-list'); }
return false;
});
});
})(jQuery);
最后,任务列表中每个项目的 done
链接绑定一个 live
事件。通过使用 live()
函数代替 bind()
函数或者 click()
等快捷方式,所有匹配 #task-list
的元素都绑定到单击事件函数,即使这些元素在 live()
调用时尚不存在。这样就能够为每个新项插入“done”链接,不需要在每次插入时重新绑定单击事件。
当一个项标记为完成时,它就从列表中删除,更新的列表用 task-list
键码存储在本地存储中。当保存更新的列表时需要多加小心:
if( taskList ) { $.store('task-list',taskList); }
else { $.remove('task-list'); }
当列表中的最后一项删除时, taskList
变量将为空。这会导致求 store()
函数的值时就像用单一参数(而不是两个参数)调用的情况。当 store()
接收单一参数时,读取具有该键码的项目,不修改保存列表。目标是保存一个空列表。 else
子句中的 remove()
函数删除 task-list
键码和相关值。这能满足为空白列表设置保存状态的目标。