Skip to content

跨页面通信

web

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