跨页面通信
onstroage 事件
js
localStorage.setItem('a', 1)
window.addEventListener('storage', (e) => console.log(e))
iframe
1. 利用 hash 变化实现父子组件通信
父窗口
html
<iframe name="myIframe" src="http://localhost:1000/2.html"></iframe>
js
var originURL = myIframe.location.href
var i = document.querySelector('iframe')
i.onload = function () {
//这是异步加载的iframe
i.src += '#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
}
子窗口
js
window.onhashchange = function () {
console.log(window.location.hash)
}
2.父调用子页面的 js 或者反过来调用
js
// 父
var i = document.querySelector('iframe')
i.onload = function () {
myIframe.window.f()
}
//子
function f() {
console.log('this is 2.html')
}
js
//子
parent.fn1()
//父
function fn1(s) {
console.log('this is 1.html')
}
MessageChannel
顾名思义,信息通道。允许我们创建一个新的消息通道,并通过它的两个MessagePort 属性发送数据m,而且在 Web Worker 中可用。可以控制台打印,发现有两个属性,portl1和port2。一个页面内嵌与iframe最常用这种方法。
就像一条管道,一边出一边进,我们可以给postmessage方法加上第三个参数:
js
var channel = new MessageChannel();
channel.port1.addEventListener("message", function(e){
window.parent.postMessage(e,'*',[channel.port2]);
channel = null;
});
js
let channel = new MessageChannel()
let { port1, port2 } = channel
port1.onmessage = function (event) {
console.log('port2=>port1', event.data)
}
port2.onmessage = function (event) {
console.log('port1=>port2', event.data)
}
port1.postMessage('port1给port2发送数据')
port1.postMessage('port1给port1发送数据')
非同源的两个页面
A 通过 iframe 内嵌 B, 通过 postMessage 向 B 发送消息. B:1.addEventListener('stroge', (e) => {localStorage.setItem('a', 1)}) 2.addEventListener('message', (e) => console.log(e))
深拷贝
js
var obj = { a: 1, b: 2, c: { d: 3, e: [{ f: 1, g: 2 }] }, h: null }
obj.h = obj
var res
async function copy(obj) {
return new Promise((resolve) => {
var channel = new MessageChannel()
channel.port2.onmessage = (ev) => resolve(ev.data)
channel.port1.postMessage(obj)
})
}
;(async () => {
res = await copy(obj)
console.log(res)
})()