浏览器跨窗口通信
定时器 + 客户端存储
在一个页面将数据存储起来,然后再另一个页面使用定时器刷新数据就可以了。
定时器:setTimeout/setInterval/requestAnimationFrame
客户端存储: cookie/localStorage/sessionStorage/indexDB/chrome的FileSystem
page1
var messageEl = document.getElementById("inputMessage"); var btnSend = document.getElementById("btnSend"); btnSend.addEventListener("click", function () { var message = messageEl.value; sessionStorage.setItem( "ls-message1", JSON.stringify({ date: Date.now(), message, from: "page 1" }) ); });
page2
var messagesEle = document.getElementById("messages"); var messageEl = document.getElementById("inputMessage"); var lastMessage = null; setInterval(() => { var message = sessionStorage.getItem("ls-message1"); try { if (message) { message = JSON.parse(message); if (!lastMessage || lastMessage.date != message.date) { appendMessage(message); lastMessage = message; } } } catch (err) { console.log(err); } }, 200); function appendMessage(data) { var msgEl = document.createElement("p"); msgEl.innerText = data.date + "\n " + data.from + "\n" + data.message; messagesEle.appendChild(msgEl); }
postMessage
index
var messageEl = document.getElementById("inputMessage"); var receiver = document.getElementById("receiver"); var btnSend = document.getElementById("btnSend"); btnSend.addEventListener("click", function (e) { e.preventDefault(); var message = messageEl.value; console.log(message); receiver.contentWindow.postMessage(JSON.stringify({ date: Date.now(), message, from: "index" })) });
page1
var messagesEle = document.getElementById("messages"); window.addEventListener('message', function (e) { // 监听 message 事件 console.log(e); let data = JSON.parse(e.data) var msgEl = document.createElement("p"); msgEl.innerText = data.date + " \n" + data.from + "\n" + data.message; messagesEle.appendChild(msgEl); });
StorageEvent
本地存储localStorage在存储数据时,会触发storage,在Page 1设置消息, Page 2注册storage事件,就能监听到数据的变化了。
page1
1 2 3 4 5 6 7 8 9 10 11 | btnSend.addEventListener( "click" , function () { var message = messageEl.value; localStorage.setItem( "ls-message" , JSON.stringify({ date: new Date().toLocaleString(), message, from: "page 1" }) ); }); |
page2
window.addEventListener("storage", function (e) { console.log(e) if (e.key === "ls-message") { var msgEl = document.createElement("p"); var data = JSON.parse(e.newValue); msgEl.innerText = data.date + " \n" + data.from + "\n" + data.message; messagesEle.appendChild(msgEl); } });
storage事件的storageEvent有下面特有的属性(都是只读):
- key :代表属性名发生变化.当被clear()方法清除之后所有属性名变为null
- newValue:新添加进的值.当被clear()方法执行过或者键名已被删除时值为null
- oldValue:原始值.而被clear()方法执行过,或在设置新值之前并没有设置初始值时则返回null
- storageArea:被操作的storage对象
- url:key发生改变的对象所在文档的URL地址
Broadcast Channel
Broadcast Channel用于多窗口,使用时先 创建BroadcastChannel, 然后监听事件。需要注意的是,在注册时,目标页面和源页面的渠道名称要保持一直
page1
var channel = new BroadcastChannel("channel-BroadcastChannel"); var messageEl = document.getElementById("inputMessage"); var btnSend = document.getElementById("btnSend"); btnSend.addEventListener("click", function () { var message = messageEl.value; channel.postMessage({ date: new Date().toLocaleString(), message, from: "page 1" }); });
page2
var messagesEle = document.getElementById("messages"); var channel = new BroadcastChannel("channel-BroadcastChannel"); channel.addEventListener("message", function (ev) { console.log(ev); var msgEl = document.createElement("p"); msgEl.innerText = ev.data.date + "\n" + ev.data.from + "\n" + ev.data.message; messagesEle.appendChild(msgEl); });