html5本地存储localStorage实战

本文总结了web本地存储方案,包括Cookie、FlashSharedObject、GoogleGears、localStorage等,并详细介绍了localStorage的使用方法及其实战应用,如评论表单记忆、浏览历史记录存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

web本地存储方案总结

本地存储解决方案很多,比如Flash SharedObject、Google Gears、Cookie、DOM Storage、User Data、window.name、Silverlight、Open Database等。
借用网上的一张图来看下目前主流的本地存储方案:

Cookie在web中得到广泛应用,但局限性非常明显,容量太小,有些站点会因为出于安全的考虑而禁用cookie,cookie没有想象中的那么安全。
Flash SharedObject之前明河有过介绍,有兴趣的朋友可以看《如何使用kissy的flash本地存储》,使用的是kissy的store模块来调用Flash SharedObject。Flash SharedObject的优点是容量适中,基本上不存在兼容性问题,缺点是要在页面中引入特定的swf和js文件,增加额外负担,处理繁琐;还是有部分机子没有flash运行环境。
Google GearsGoogle的离线方案,已经停止更新,官方推荐使用html5的localStorage方案。
User DataIE的早期版本的本地存储方案,看上去有点怪异,有兴趣的朋友可以看《跨浏览器的本地存储方案一》

localStorage

相对于上述本地存储方案,localStorage有自身的优点:容量大、易用、强大、原生支持;
缺点是兼容性差些(主要是IE8以下版本不支持)、安全性也差些(所以请勿使用localStorage保存敏感信息)。

localStorage的API

非常通俗易懂的接口

  • localStorage.getItem(key):获取指定key本地存储的值
  • localStorage.setItem(key,value):将value存储到key字段
  • localStorage.removeItem(key):删除指定key本地存储的值

留意localStorage存储的值都是字符串类型,在处理复杂的数据时,比如json数据时,需要借助JSON类,将json字符串转换成真正可用的json格式,localStorage第二个实战教程会重点演示相关功能。
localStorage还提供了一个storage事件,在存储的值改变后触发,比如下面代码:

  1. if(window.addEventListener){
  2. window.addEventListener(“storage”,storageHandler,false);
  3. } elseif(window.attachEvent){
  4. window.attachEvent(“onstorage”,storageHandler);
  5. }
  6. function storageHandler(ev){
  7. if(!ev){ev=window.event;}
  8. console.log(‘改变的字段是’+ev.key);
  9. console.log(‘旧的值是’+ev.oldValue);
  10. console.log(‘新的值是’+ev.newValue);
  11. }
明河整理的LS类

明河对localStorage进行了封装,写成LS,目前只是显示基础功能,日后会强化这个类,希望可以成为一个通用解决方案。

  1. /**
  2. * @fileOverview html5本地存储(日后有可能会发布兼容IE8以下版本的IE的本地存储类)
  3. * @author 明河<minghe36@126.com>
  4. * @version 1.0
  5. * @example
  6. *          LS.item(“key”,”value”);//设置key字段为value
  7. *          LS.item(“key”);//设置key字段的值
  8. */
  9. var LS ={
  10. /**
  11. * 获取/设置存储字段
  12. * @param {String} name 字段名称
  13. * @param {String} value 值
  14. * @return {String}
  15. */
  16. item :function(name,value){
  17. varval =null;
  18. if(LS.isSupportLocalStorage()){
  19. if(value){
  20. localStorage.setItem(name,value);
  21. val =value;
  22. }else{
  23. val =localStorage.getItem(name);
  24. }
  25. }else{
  26. console.log(‘浏览器不支持html5的本地存储!’);
  27. }
  28. returnval;
  29. },
  30. /**
  31. * 移除指定name的存储
  32. * @param {String} name 字段名称
  33. * @return {Boolean}
  34. */
  35. removeItem :function(name){
  36. if(LS.isSupportLocalStorage()){
  37. localStorage.removeItem(name);
  38. }else{
  39. console.log(‘浏览器不支持html5的本地存储!’);
  40. returnfalse;
  41. }
  42. returntrue;
  43. },
  44. /**
  45. * 判断浏览器是否直接html5本地存储
  46. */
  47. isSupportLocalStorage :function(){
  48. varls =LS,is =ls.IS_HAS_LOCAL_STORAGE;
  49. if(is ==null){
  50. if(window.localStorage){
  51. is =ls.IS_HAS_LOCAL_STORAGE =true;
  52. }
  53. }
  54. returnis;
  55. },
  56. IS_HAS_LOCAL_STORAGE :null
  57. };
如何调用?

我们先来创建个评论表单:

  1. <formaction=”">
  2. <p><labelfor=”user”>用户名</label></p>
  3. <p><inputtype=”text”size=”25″value=”"id=”user”name=”user”class=”form-field”></p>
  4. <p><labelfor=”email”>邮箱</label></p>
  5. <p><inputtype=”email”size=”25″value=”"id=”email”name=”email”class=”form-field”></p>
  6. <p><labelfor=”site”>网站</label></p>
  7. <p><inputtype=”url”size=”25″value=”"id=”site”name=”site”class=”form-field”></p>
  8. </form>

接下来我们希望入框失去焦点后记忆输入框的值:(记忆三个字段:用户名、邮箱、网站,这样用户下次进入博客评论时无需重复输入这三个表单域)

  1. $(function(){
  2. varval;
  3. //表单内的输入框失去焦点后将数据写入本地存储(字段为输入框id名)
  4. $(‘.form-field’).bind(‘blur’,function(){
  5. LS.item($(this).attr(‘id’),$(this).val());
  6. })
  7. //遍历输入框,获取本地存储的相应字段的值,写入到表单输入框内
  8. .each(function(){
  9. val =LS.item($(this).attr(‘id’));
  10. if(val !=null) $(this).val(val);
  11. });
  12. })

监听输入框的blur事件,获取该输入框的id作为存储的key名,输入框的值自然是需要存储的值。
在页面结束后,我们还需要遍历下输入框,看看该id存不存在本地储存的值,如果有,将其写入到输入框。

 

Histories主要有以下几个功能:
  • 显示浏览历史文章列表
  • 可以保存文章数据
  • 可以清理数据

 

将json字符串存入本地存储

保存浏览历史,比保存评论信息,有个难得地方,就是数据的处理,一条浏览历史,包含文章id、url、标题,或者图片之类的,明显我们不能使用上一篇教程的方式,一个一个存储,那样成本太高了。
我们需要一个存储字段,能够包含所有的的数据,比如是下面的形式:(默认保存在data-histories字段)

  1. [{'id' :1,'title' :'第1篇文章标题','url' : 'http://www.36ria.com/'},
  2. {'id' :2,'title' :'第2篇文章标题','url' : 'http://www.36ria.com/'},
  3. {'id' :3,'title' :'第3篇文章标题','url' : 'http://www.36ria.com/'},
  4. {'id' :4,'title' :'第4篇文章标题','url' : 'http://www.36ria.com/'}
  5. ]


上图截自明河本地运行demo后的本地存储情况。

保存单条数据
  1. vardata ={‘id’ :id,’title’ :’第’+id+’篇文章标题’,'url’ : ’http://www.36ria.com/’};
  2. //保存数据
  3. histories.save(data);

demo中的id是明河用随机数模拟出来的,最后调用Histories类的save方法,将数据追加到存储字段data-histories内。
接下来我们来看Histories的save方法,做了哪些处理。

  1. /**
  2. * 将值保存到本地数据
  3. * @param {Object} singleData 文章数据
  4. * @return {Boolean}
  5. */
  6. save :function(singleData){
  7. varself =this,config =self.config,ls =config.ls,sData;
  8. //保存的数据类型必须为对象
  9. if(typeofsingleData ==’object’){
  10. //如果已经存在该条数据,直接退出
  11. if(self.isExist(singleData.id))returnfalse;
  12. //删除多余数据
  13. self._removeExceedPost();
  14. //向数据缓存追加一条数据
  15. self.data.unshift(singleData);
  16. //转化成json字符串
  17. sData =JSON.stringify(self.data);
  18. //调用本地存储类,保存数据
  19. ls.item(config.storeName,sData);
  20. }
  21. returntrue;
  22. }

代码中有几个关键点,明河说明下:

对文章id进行判断,如果已经存在该数据,直接退出save
  1. //如果已经存在该条数据,直接退出
  2. if(self.isExist(singleData.id))returnfalse;
向数据数组前面插入数据
  1. self.data.unshift(singleData);

self.data为数据数组,unshift是js数组方法,前插数据,跟push的作用相反。

将单条数据转化成json字符串
  1. //转化成json字符串
  2. sData = JSON.stringify(self.data);

JSON是jquery内置的对象,用于处理json,这里将json数据转成字符串,最后保存到data-histories。

输出列表
  1. <ulid=”histories”>
  2. </ul>
  1. varhistories =new Histories();
  2. //添加历史数据列表
  3. histories.appendTo(‘#histories’);

appendTo方法,会把列表数据加入到指定容器内。
接下来来看下appendTo这个方法,做了哪些处理。

  1. /**
  2. * 将数据加入dom
  3. * @param {String} container 容器
  4. */
  5. appendTo :function(container){
  6. varself =this,$container = $(container),html = ”,data =self.getData(),config =self.config,maxTitleLen =config.maxTitleLen,tpl =config.tpl,count=config.count;
  7. if($container.length == 0 || data.length ==0)returnfalse;
  8. //遍历数据(数组)
  9. $.each(data,function(i){
  10. //截取标题
  11. this.title =this.title.substr(0,maxTitleLen);
  12. //转换模板
  13. html +=tpl.TFtpl(this);
  14. //超过最大渲染数,直接退出循环
  15. if(i >=count)returnfalse;
  16. });
  17. return $(html).appendTo($container);
  18. },
获取json数据
  1. data =self.getData();

getData方法,会将json字符串转成json对象:

  1. /**
  2. * 获取本地数据
  3. * @return {Array}
  4. */
  5. getData :function(){
  6. varself =this,config =self.config,ls =config.ls,sData =ls.item(config.storeName);
  7. if(sData)self.data =JSON.parse(sData);
  8. returnself.data;
  9. }

留意下面的代码:

  1. self.data =JSON.parse(sData);

parse是JSON很重要的方法,会将json数据字符串,转换成json对象。

列表模板
  1. //列表的li模板
  2. tpl :’<li data-id=”{id}”><a href=”{url}” target=”_blank”>{title}</a></li>’

我们需要模板是可配置的,appendTo这个方法最主要的工作就是解析模板,然后把html片段添加到容器内。

解析模板
  1. //遍历数据(数组)
  2. $.each(data,function(i){
  3. //截取标题
  4. this.title =this.title.substr(0,maxTitleLen);
  5. //转换模板
  6. html +=tpl.TFtpl(this);
  7. //超过最大渲染数,直接退出循环
  8. if(i >=count)returnfalse;
  9. });

TFtpl是明河写的简单的模板解析方法:

  1. //简单的转换模板函数
  2. String.prototype.TFtpl =function(o){
  3. returnthis.replace(/{([^{}]*)}/g,
  4. function(a,b){
  5. varr =o[b];
  6. returntypeofr===’string’?r:a;
  7. }
  8. );
  9. };

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值