里长办公室广播:张君雅小妹妹,恁兜欸泡面已经煮好了!
前两天已经认识了 PostMessage 和建立专属频道的 MessageChannel,它们都是进行点对点的沟通,但如果想要一次跟多个页面沟通时怎麽办了,这时 BroadcastChannel 就能派上用场了。
BroadcastChannel 就如同一个无线对讲机系统,讯息是播放在一个广播频道中,任何页面只要取得频道的频率就可以在无线电中发送/接收讯息。
和 MessageChannel
一样,BroadcastChannel
本身也是一个 Class
,只要透过关键字 new
就能建立一个广播频道,不过这次我们要传入一个字串来当作广播频道的名称,未来其他页面才能藉由同样的字串来进入频道。
const channel = new BroadcastChannel("max_channel");
接着只要透过我们建立的广播频道送出讯息即可:
const channel = new BroadcastChannel("max_channel");
channel.postMessage("你已成功加入频道!", location.origin);
要收到讯息的话就用 BroadcastChannel 监听 message
即可:
const channel = new BroadcastChannel("max_channel");
channel.onmessage = function (event) {
console.log(event.data);
};
这时候其他页面只要使用同样的频道名称建立一个 BroadcastChannel,并且一样透过该频道来传送/接收讯息,这样所有频道中的页面就都可以相互沟通了。
<!-- 这里是 main.html -->
<button onclick="sendMessage()">send message</button>
<iframe src="pageA.html" width="480" height="120"></iframe>
<iframe src="pageB.html" width="480" height="120"></iframe>
<script>
const channel = new BroadcastChannel("max_channel");
channel.onmessage = function (event) {
console.log(event.data);
};
function sendMessage() {
channel.postMessage("你已成功加入频道!", location.origin);
}
</script>
<!-- 这里是 pageA.html -->
<button onclick="sendMessage()">send message</button>
<div class="output">pageA content</div>
<script>
const output = document.querySelector(".output");
const channel = new BroadcastChannel("max_channel");
channel.onmessage = function (event) {
const output = document.querySelector(".output");
output.innerHTML = event.data;
};
function sendMessage() {
channel.postMessage("pageA 发送讯息!", location.origin);
}
</script>
<!-- 这里是 pageB.html -->
<button onclick="sendMessage()">send message</button>
<div class="output">pageB content</div>
<script>
const channel = new BroadcastChannel("max_channel");
channel.onmessage = function (event) {
const output = document.querySelector(".output");
output.innerHTML = event.data;
};
function sendMessage() {
channel.postMessage("pageB 发送讯息!", location.origin);
}
</script>
不过上面这样的范例,会有一个令人诟病的地方,就是「频道名称」的同步问题,要是有其中某个页面打错频道名称,那就会连不上频道。或是如果想要更换频道名称的时候,就必须大家一起改,似乎是又点不太方便。
所以在主页面建立频道後,其实可以先用一般的 postMessage
将频道名称传给需要的页面:
<iframe src="pageA.html" width="480" height="120"></iframe>
<iframe src="pageB.html" width="480" height="120"></iframe>
<script>
const allIframe = document.querySelectorAll("iframe");
const channel = new BroadcastChannel("max_channel");
// 发送频道名称
allIframe.forEach((iframe) => {
iframe.addEventListener("load", function () {
this.contentWindow.postMessage(channel.name, location.origin);
});
});
channel.onmessage = function (event) {
console.log(event.data);
};
</script>
<!-- 这里是 pageA.html -->
<div class="output">pageA content</div>
<script>
let channel;
window.addEventListener("message", function (event) {
if (event.origin !== location.origin) return;
channel = new BroadcastChannel(event.data);
channel.onmessage = function (bc_event) {
const output = document.querySelector(".output");
output.innerHTML = event.data;
};
channel.postMessage("pageA 加入频道", location.origin);
});
</script>
<!-- 这里是 pageB.html -->
<div class="output">pageB content</div>
<script>
let channel;
window.addEventListener("message", function (event) {
if (event.origin !== location.origin) return;
channel = new BroadcastChannel(event.data);
channel.onmessage = function (bc_event) {
const output = document.querySelector(".output");
output.innerHTML = event.data;
};
channel.postMessage("pageB 加入频道", location.origin);
});
</script>
补充:如果有页面想要与广播频道断开连结的话,只要拿建立的频道执行
close()
即可,关闭後频道还是存在,只是该页面不再接收频道的讯息。
这三天我们已经完全认识了 PostMessage,了解到它不但可以传送讯息,还可以建立私讯或群组的通讯模式,而这项技术其实时常会用在 Web Worker 中,但因为它的范畴有点庞大,所以这次的系列文章不会介绍到,有兴趣的朋友可以再自行研究~
>>: Alpine Linux Porting (1.11?)
不变,不代表会更快更好 要求不变,反而会花过多时间追求完美 在[Day22] Scrum失败经验谈 ...
前言 在上一章我们知道如何在一台机器上使用多张 GPU 来Training,这对我们 Train 大...
其实不用安装requests就可以下载东西 python的urllib.request.urlope...
Pandas汇入CSV档 # 载入pandas import pandas as pd if __n...
因为看到有人反应,重覆登出登入,会造成记忆体使用量增加,这实在是让人太好奇了,所以就想来实测一下。但...