h5新API之WebStorage解决页面数据通信问题
localStorage相信大家都不陌生,今天我们要讨论的不是怎么存储数据,获取数据。而是看看WebStorage的一些妙用,相信大家在开发中遇到过这样一个场景,一个页面中嵌套一个iframe,iframe中填写了一些数据,关闭iframe后,需要通知页面中变化数据,或者触发某个事件。这个需求说难不难,说简单不简单,解决方式也是五花八门,读者可以在评论区留言。我要说的是,用storage事件机制来解决这个问题。
引用《h5移动web开发指南》上的话:
“当同源页面的某个页面修改了localStorage
,其余的同源页面只要注册了storage事件,就会触发”
所以,localStorage
的例子运行需要如下条件:
- 同一浏览器打开了两个同源页面
- 其中一个网页修改了
localStorage
- 另一网页注册了
storage
事件
很容易犯的错误是,在同一个网页修改本地存储,又在同一个网页监听,这样是没有效果的。
例子
网页A:监听了storage
事件:
<!DOCTYPE html> <html> <head lang="en"> <title>A</title> </head> <body> <h1 id="ss"></h1> <script> ss.innerHTML=localStorage.getItem("foo"); window.addEventListener("storage", function (e) { ss.innerHTML=e.newValue; }); </script> </body> </html>
网页B:修改了localStorage
<!DOCTYPE html> <html> <head lang="en"> <title>B</title> </head> <body> <div> <h3 id="aa">current value: 0</h3> <button id="cc">change</button> </div> <script> var i=0; cc.addEventListener("click",function(){ localStorage.clear(); aa.innerHTML="current value: "+i; localStorage.setItem('foo', i++); }) </script> </body> </html>
是不是很神奇?连个标签之间竟然产生了通信。
<!DOCTYPE html> <html> <head lang="en"> <title>A</title> </head> <body> <h1 id="cc"></h1> <button id="change">change</button> <script> localStorage.setItem("xx","val"); var val=localStorage.getItem("xx"); cc.innerHTML=val; var orignalSetItem = localStorage.setItem; localStorage.setItem = function(key,newValue){ var setItemEvent = new Event("setItemEvent"); setItemEvent.newValue = newValue; window.dispatchEvent(setItemEvent); orignalSetItem.apply(this,arguments); } window.addEventListener("setItemEvent", function (e) { cc.innerHTML=e.newValue; }); change.addEventListener("click",function () { localStorage.setItem("xx","1234"); }) </script> </body> </html>
这里用到了自定义事件,也是H5新增API
通过iframe方式也可以达到目的
<!DOCTYPE html> <html> <head lang="en"> <title>B</title> </head> <body> <div> <h3 id="aa">current value: 0</h3> <button id="cc">change</button> </div> <iframe src="a.html" frameborder="0"></iframe> <script> var i=0; cc.addEventListener("click",function(){ localStorage.clear(); aa.innerHTML="current value: "+i; localStorage.setItem('foo', i++); }) </script> </body> </html>