1.说明
localStorage和sessionStorage两者的区别在于存储的有效性和作用域不同:数据可以存储多长时间以及谁拥有对数据的访问权。通过localStorage存储的数据时永久性的,除非web应用刻意删除存储的数据,或者用户通过设置浏览器配置来删除,否则数据将一直保留在用户的电脑上,永不过期。localStorage的作用域是限制在文档源级别的。文档源是通过协议、主机名及端口三者来确定的。同源的文档共享同样的localStorage数据。它们可以互相读取对方的数据、甚至可以覆盖对方的数据(即使它们运行的脚本来自同一台第三方的服务器也不行)。注意:localStorage的作用域也受浏览器供应商的限制。如果使用firefox访问站点,那么下次用另一个浏览器再次访问的时候,本次是无法获取上次存储的数据的。
sessionStorage存储的数据,一旦窗口或者标签页被永久性关闭了,那么所有通过sessionStorage存储的数据也都被删除了。(当然要浏览的是,现在浏览器已经具备了重新打开最近关闭的标签页随后恢复上一次浏览的会话功能,因此,这些标签页以及与之相关的sessionStorage的有效期可能会更长一些)。它的作用域也是限制在窗口中,如果同源的文档渲染在不同的浏览器标签页中,那么它们互相之间拥有的是各自的sessionStorage数据,无法共享;一个标签页中的脚本时无法读取活覆盖另一个标签页脚本写入的数据。哪怕两个标签页渲染的是同一个页面,运行的是同一个脚本。其实就是说sessionStorage仅对某个会话有效。
sessionStorage和localStorage的clear()函数,用于清空同源的本地存储数据,比如localStorage.clear(),它将删除所有同源的本地存储的localStorage数据,而对于sessionStorage,它只清空当前会话存储的数据。
关闭页面会导致sessionstorage的数据被清除,但刷新活重新打开被关闭页面数据还是存在的,如果需要存储的只是少量的临时数据。我们可以使用sessionstorage。或者做页面间的小交互。
sessionStorage和localStorage具有相同的方法storage事件,在存储事件的处理函数中是不能够取消这个存储动作的。存储事件只是浏览器再数据变化发生之后给你的一个通知。注意,这里的条件是数据真的发生了变化。也就是说,如果当前的存储区域是空的,你再去调用clear()是不会触发事件的。或者你通过setItem()来设置一个与现有值相同的值,事件也是不会触发的。当存储去也发生改变时就会被触发,这其中包含很多有用的属性:
1、storageArea:表示存储类型(session或local) 2、key:发生改变项的key 3、oldValue:key的原值 4、newValue:key的新值 5、url*:key改变发生的URL
注意:url属性早期的规范中为uri属性。有些浏览器发布较早,没有包含url属性,则应该使用uri属性。如果调用clear()方法,那么key、oldValue和newValue都会被设置为null
PS.在firefox和chrome中存储和读取都是正常的, 但是对storage事件的触发似乎有点问题, 自身页面进行setItem后没有触发window的storage事件, 但是同时访问A.html和B.html, 在A页面中进行 setItem能触发B页面中window的storage事件, 同样的在B页面中进行setItem能触发A页面中window的storage事件. 在IE9中, 页面自身的设值能触发当前页面的storage事件,同样当前页面的设值能触发同一”起源”下其他页面window的storage事件,这看起来似乎更让人想的通些
2.localStorage
localStorage.getItem(key) //获取指定key本地存储的值 如果key不存在返回null localStorage.setItem(key,value) //将value存储到key字段 如果key存在时 更新value localStorage.removeItem(key) //删除指定key本地存储的值 一旦删除 key对应的数据将会全部删除 localStorage.clear() //某些时候使用removeItem逐个删除太麻烦,可以使用clear,执行的后果是会清 //除所有localStorage对象保存的数据
tips:但是自己观察localStorage存储的值都是字符串类型 在处理复杂的数据时,比如json数据时 需要借助JSON类 将json字符串转换成真正可用的json格式
3.sessionStorage
sessionStorage.getItem(key) //获取指定key本地存储的值 sessionStorage.setItem(key,value) //将value存储到key字段 sessionStorage.removeItem(key) //删除指定key本地存储的值 sessionStorage.length //是sessionStorage的项目数
以上两者都用下述方法遍历
//length属性及key()方法 传入0~length-1的数字 可以枚举所有存储数据的名字 for(vari=0;i<localStorage.length;i++){ var name = localStorage.key(i); var value = localStorage.getItem(name); }
4.存储事件storage
无论什么时候存储在localStorage或者sessionStorage的数据发生改变,浏览器都会在其他对该数据可见的窗口对象上触发存储事件(但是,在对数据进行改变的窗口对象上是不会触发的)如果浏览器有两个标签页面都打开来自同源的页面,其中一个页面在localStorage上存储了数据,那么另外一个标签页就会接收到一个存储事件。sessionStorage的作用域是限制在顶层窗口的,因此对sessionStorage的改变只有当有相牵连的窗口的时候才会触发存储事件。还要注意,只有当存储数据真正发生改变的时候才会触发存储事件。像给已经存在的存储项设置一个一模一样的值,抑或是删除一个本来就不存在的存储项都是不会触发存储事件的。
为了存储事件注册处理程序可以通过addEventListener()方法或attachEvent()方法。在绝大多数浏览器中,还可以使用window对象设置onstorage属性的方式,不Firefox不支持。
与存储事件相关的事件对象有5个非常重要的属性(遗憾的是,IE8不支持它!!!)
l key:被设置或者移除的项的名字或键名。如果调用的是clear()函数,那么该属性值为null
l newValue:保存该项的新值;或者调用removeItem()时,该属性值为null。
l oldValue:改变或者删除该项,保存该项原先的值;当插入一个新项的时候,该属性值为null。
l storageArea:这个属性值就好比是目标Window对象上的localStroage属性或是sessionStorage属性
l url:触发该存储变化脚本所在的文档的URL
注意:localStroage和存储事件是采用广播机制的,浏览器会对目前正在访问的同样的站点的所有窗口发送消息。
5.说点其他的小尾巴
<script type="text/javascript"> if (localStorage.pagecount) { localStorage.pagecount=Number(localStorage.pagecount) +1; } else { localStorage.pagecount=1; } if (localStorage.pagecount == 1) { window.location.href="home.html"; //这里也可以换成APPCAN的打开窗口API } else { document.write("你一共运行本页面共计: "+ localStorage.pagecount + " 次"); } </script> //当首次运行后,运行home.html文件 //后升级客户端,在index.html没修改的情况, localStorage.pagecount //继续计数 //当删除客户端重新安装后, localStorage.pagecount 重新计数
6.小尾巴的小尾巴 Dot写法举栗子
在localStroage 存在所谓Dot的写法
其实Dot呢 dot.js是一个模板框架 在web前端使用 说的再简单点就是dot.js作为模板引擎
主要的用途就是 在写好的模板上 放进数据 生成含有数据的html代码还是bu懂吗 再举个栗子
doT.template( template )( obj ) //代码解释:把模板template,作为参数 //传入doT.template() 方法,dot就把模板处理一下,然后你再把数据对象传 //入,返回值,就是html与数据 一起生成的html代码了,再拼接到页面即 //可;
写一个栗子吧
用dot方式来操作( 每次以’hello’=>’world’,’zhangsan’=>’lisi’来做为例子)
设值 localStorage.hello = 'world'; localStorage.zhangsan = 'lisi'; 取值: var value_of_hello_in_localStorage = localStorage.hello; var value_of_zhangsan_in_localStorage = localStorage.zhangsan
用getItem setItem来操作
设值: localStorage.setItem("hello", "world"); localStorage.setItem("zhangsan", "lisi"); 取值: localStorage.getItem("hello"); localStorage.getItem("zhangsan");
这两种方法的效率我不清楚,但是为什么推荐使用get setItem呢?
1.容易控制,便于动态绑定,尤其在函数抽离和重构中。比如我要存一个复杂类型,每次存的时候都需要做JSON.stringify(object_a),所以我把它抽成函数
//用dot方式来实现设值: function storage_object(key,object_value) { localStorage.key = JSON.stringify(object_value); } //用getItem方式来实现: function storage_object (key,object_value) { localStorage.setItem(key,JSON.stringify(object_value)); }
这时候就会明显的发现用dot的方式是很不合适的。因为他不能实现动态的绑定key。所以对于新手来说 乖乖从简单的开始敲吧
在度娘的时候我看到这么一段代码 现在还是不太理解 但是有些注释可以拿来参考一下
var show = 0; //定义默认展示的是第一个TAB选中状态 if (window.localStorage){ //如果浏览器支持localStorage var navShow = localStorage.getItem("shownum"); //获取客户端TAB状态 if(navShow==null){ //如果为空,即第一次打开 //将默认的第一个TAB设置为选中状态并显示与其对应的list $("#nav ul li").eq(show).addClass("cur").siblings().removeClass("cur"); $(".list").eq(show).show().siblings().hide(); } $("#nav ul li").each(function(index){ //遍历每个TAB var li = $(this); show = li.attr("cur")==true?index:show; //如果当前TAB被点击选中,则将show值设为当前的索引值 if(index==navShow){ //如果当前索引值与存储的TAB状态值一致 li.addClass("cur"); //设置为选中状态样式 $(".list").eq(index).show().siblings().hide(); //显示对应的list } li.click(function(){ //当单击当前TAB时 li.addClass("cur").siblings().removeClass("cur");//设置为选中状态样式 $(".list").eq(index).show().siblings().hide(); //显示对应的list localStorage.setItem("shownum",index); //将TAB选中状态存储到本地 }); }); }else{//如果浏览器不支持localStorage alert('您的浏览器不支持localStorage.'); }
8.这个真的是卖萌的小尾巴了!举个大栗子!!
假设 我们需要用0和1 来标记某种对象的状态 然后我们记录一大串的对象状态
那么先把这一大(羊肉)串的对象的状态塞入一个数组数组中 js的数组用push命令 (没啥 我就是复习一下)
<script type="text/javascript"> var arrList = [0,1,1,1,1,0,1] //将之存起来 if (window.localStorage) { localStorage.setItem("Item", arrList); } else { Cookie.write("Item", arrList); } //每次需要将这一大(羊肉)串的状态取出来使用的时候 比如说每次载入界面 var storeDate = window.localStorage?localStorage.getItem("Item"): Cookie.read("Item"); //需要注意的是:虽然我们存储的是数组,但是,实际上存储的的是数组字符化后 //的字符串(Cookie和localStorage都是),因此,我们在处理storeDate的时 //候,一定要当作字符串处理,类似下面: storeDate.split(",").each(function(display, index) { //根据存储的display触发相对应的动作 }); </script>