起因:
工作中时常会遇到需要在自己的项目里嵌入其他的网页,特别是出现在多家公司合作时。如果不存在跨越问题,可以直接给window绑定一个变量存值,使用这个中间变量进行双方的传值。但如果存在跨越问题则上述方式就不适用,因为可以考虑通过postMessage方式传值。下面我们简单演示在页面中嵌入其他地址的页面并实现父子级页面的传值。
制作子页面
<body>
测试子页面
<div id="send">点击发送</div>
</body>
<script>
var dom = document.getElementById('send')
dom.addEventListener("touchend", sendData)
function sendData() {
console.log('点击发送');
window.parent.postMessage({ sendData: '传给父页面的数据' }, '*');
}
</script>
这里我们可以将子页面放到服务器上,为了便于测试,我将这个页面放到github上托管,生成请求地址https://cxyeve.github.io/testPage/。
子页面向父页面传值通过下面这句代码
window.parent.postMessage({ 变量的key: '变量的value' },
'父页面的地址,如果不限制则传*');
制作父页面
<div>父页面</div>
<div style="width:200px;height:200px;border:1px solid #333;">
<iframe src="https://cxyeve.github.io/testPage"
style="width:100%;height:100%;"
frameborder="0" border="0"
marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes"></iframe>
</div>
此时,我们用以服务器地址方式打开父页面,如用live server,页面如下(十分简陋)
image.png
父页面监听子页面的传值可通过以下代码
window.onmessage = (e) => {
console.log('传递的参数', e.data);
if (e.data.sendData) {
console.log('sendData的值', e.data.sendData);
}
}
点击后控制台的输出如下:
image.png
以上代码注意两点:
window.parent.postMessage不要赋值给变量后调用,此方式无效。错误如下:
//这种写法无效
var postMsg = window.parent.postMessage
postMsg({ sendData: '传给父页面的数据' }, '*')
2.子页面自己发送,又自己监听,导致父页面监听不到。我当时是对方公司的前端写完后想测试有没有成功发送数据就在子页面加了监听,以为不会影响到父页面。而后造成他那边子页面确定发送了数据,我这边的父页面死活监听不到。错误如下:
<body>
测试子页面
<div id="send">点击发送</div>
</body>
<script>
var dom = document.getElementById('send')
dom.addEventListener("touchend", sendData)
//--------------此段代码会拦截父页面的监听,应去掉---------------
window.parent.onmessage = (e) => {
console.log('传递的参数', e.data);
if (e.data.sendData) {
console.log('sendData的值', e.data.sendData);
}
}
//--------------此段代码会拦截父页面的监听---------------
function sendData() {
console.log('点击发送');
window.parent.postMessage({ sendData: '传给父页面的数据' }, '*');
}
</script>