浏览器跨窗口通信

定时器 + 客户端存储

在一个页面将数据存储起来,然后再另一个页面使用定时器刷新数据就可以了。

定时器: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

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);
        });

posted on 2022-04-09 10:54  紅葉  阅读(81)  评论(1编辑  收藏  举报