localStorage单页面及不同页面监听变动
分析
H5本地存储有两个API,一个是Web Storage,还有一个是Web SQL。不管是哪一个,都是基于JavaScript语言来使用,而Web Storage提供了两种存储类型 API: sessionStorage 和 localStorage,二者的差异主要是数据的保存时长及数据的共享方式。
那么,如何监测本地存储webstorage的数据是否改变呢?
在H5中,window对象里面有一个storage事件,我们可以进行监听或者指定其事件处理函数的方法,在其他页面修改了sessionstorage或者localstorage中的值时,就会触发注册了storage事件。
我们先看一下几个属性:
1、event.key 属性:属性值为在 session 或 localStorage 中被修改的数据键值。
2、event.oldValue 属性:属性值为在 sessionStorage 或 localStorage 中被修改的值。
3、event.newValue 属性:属性值为在 sessionStorage 或 localStorage 中被修改后的值
4、event.url 属性:属性值为修改 sessionStorage 或 localStorage 中值的页面的URL地址
5、event.storageArea 属性 : 属性值为被变动的 sessionStorage 对象或 localStorage 对象
引用《h5移动web开发指南》上的话:
“当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发”
所以,localStorage
的例子运行需要如下条件:
- 同一浏览器打开了两个同源页面
- 其中一个网页修改了
localStorage
- 另一网页注册了
storage
事件
很容易犯的错误是,在同一个网页修改本地存储,又在同一个网页监听,这样是没有效果的。
例子
接下来我们通过两个例子来体验一下。
实时监听的页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <!DOCTYPE html> <html> <head> <meta charset= "UTF-8" > <title>利用storage事件实时监视Web Storage中的数据</title> </head> <body> <script type= "text/javascript" > //利用storage事件实时监视wev Storage中的数据 window.addEventListener( 'storage' , function (e) { //e只是一个传参 //获取被修改的键值 if (e.key == 'test' ) { //获取将要被添加内容的元素 var output = document.getElementById( 'output' ); //将获取到的修改值在元素中输出 output.innerHTML = '原有值:' + e.oldValue; output.innerHTML += '<br />新值:' + e.newValue; output.innerHTML += '<br />变动页面地址:' + utf8_decode(unescape(e.url)); //分别打印会发现内容一致 console.log(e.storageArea); console.log(localStorage); //此行代码只在Chrome浏览器中有效 console.log(e.storageArea === localStorage); //输出true } }, false ); function utf8_decode (utftext) { var string = '' ; var i = c = c1 = c2 = 0; //获取URL所有字符 while (i < utftext.length) { //获取URL并将URL中所有 Unicode 编码获取 c = utftext.charCodeAt(i); //对 Unicode 编码进行处理转化成字符串 if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c < 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } </script> <output id= "output" ></output> </body> </html> |
修改localStorage中数据的页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!DOCTYPE html> <html> <head> <meta charset= "UTF-8" > <title>用于修改localStorage 中数据的页面的代码</title> </head> <body> <script type= "text/javascript" > function setLOcalStorage () { //设置test键值下的内容等于input框中的内容 localStorage.test = document.getElementById( 'text1' ).value; } </script> 请输入一些值:<input type= "text" id= "text1" /> <button onclick= "setLOcalStorage()" >设置</button> </body> </html> |
实际效果:
代码中用到的函数:
charCodeAt() 可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。
fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串。
unescape() 可对通过 escape() 编码的字符串进行解码。
下面是关于Unicode码的一些注解:
Unicode只有一个字符集,中、日、韩的三种文字占用了Unicode中0x3000到0x9FFF的部分
Unicode目前普遍采用的是UCS-2,它用两个字节来编码一个字符, 比如汉字”经”的编码是
0x7ECF,注意字符码一般用十六进制来 表示,为了与十进制区分,十六进制以0x开头,0x7ECF
转换成十进制 就是32463,UCS-2用两个字节来编码字符,两个字节就是16位二进制, 2的16
次方等于65536,所以UCS-2最多能编码65536个字符。 编码从0到127的字符与ASCII编码的
字符一样,比如字母”a”的Unicode 编码是0x0061,十进制是97,而”a”的ASCII编码是0x61,
十进制也是97, 对于汉字的编码,事实上Unicode对汉字支持不怎么好,这也是没办法的, 简
体和繁体总共有六七万个汉字,而UCS-2最多能表示65536个,才六万 多个,所以Unicode只
能排除一些几乎不用的汉字,好在常用的简体汉字 也不过七千多个,为了能表示所有汉字,
Unicode也有UCS-4规范,就是用 4个字节来编码字符
扩展
如果非得要在同一网页监听怎么办?可以重写localStorage的方法,抛出自定义事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <script> var orignalSetItem = localStorage.setItem; localStorage.setItem = function (key,newValue){ var setItemEvent = new Event( "setItemEvent" ); setItemEvent.key = key; setItemEvent.newValue = newValue; setItemEvent.oldValue = localStorage.getItem(key); window.dispatchEvent(setItemEvent); orignalSetItem.apply( this ,arguments); } window.addEventListener( "setItemEvent" , function (e) { console.log( 'key: ' +e.key); console.log( 'newValue: ' +e.newValue); console.log( 'oldValue: ' +e.oldValue); }); localStorage.setItem( "nm" , "1234" ); </script> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具