1、准备
结构说明:在parent.html中使用iframe加载son.html和daughter.html。
分别在父窗口中获取子窗口的方法和变量;在子窗口中获取父窗口的变量和方法。
son.html跳转到daughter.html,观察parent.html的变化。
同时,父窗口监听子窗口的变量变化, 以及子窗口监听父窗口的变量变化的机制。
最后,iframe的宽高适配子窗口。
1.1 parent.html中使用iframe
<iframe id="if" name="if" scrolling="no" src="son.html" onload="load()"></iframe>
2、父子窗口获取彼此变量和方法
2.1 父窗口中获取子窗口的方法和变量
document.getElementById('if').contentWindow.list_son; // 变量
document.getElementById('if').contentWindow.son_fun(); // 方法
2.2 子窗口中获取父窗口的方法和变量
window.parent.list_parent; // 变量
window.parent.parent_fun(); // 方法
3、父子窗口分别监听彼此变量的变化
3.1 子窗口中监听父窗口变量变化
在父窗口中,变量array的内容移除一个,立即通知子窗口,而子窗口在加载时一直监听着消息。
- parent.html
list_parent.pop();
document.getElementById('if').contentWindow.postMessage({ // 参考:https://blog.csdn.net/it_java_shuai/article/details/109443125
msg: list_parent
},"*")
- son.html
window.addEventListener("message",function(event){
var data =event.data;
console.log("son --- 监听到父窗口的变量的变化" + JSON.stringify(data));
});
3.2 父窗口中监听子窗口变量变化
在父窗口中获取子窗口的值,并且改变,通知父窗口。
- parent.html
// 获取子窗口变量并修改
console.log(document.getElementById('if').contentWindow.list_son);
document.getElementById('if').contentWindow.list_son.pop();
// 这是在父窗口中改变了子窗口的变量的值,并通知到父窗口。
document.getElementById('if').contentWindow.parent.postMessage({
msg: document.getElementById('if').contentWindow.list_son
},"*");
////////////////////////////////////////////////////////////////
//父页面监听:
window.addEventListener("message", function(event){
console.log(event);
var data = event.data;
console.log("parent --- 监听到子窗口的变量的变化" + JSON.stringify(data));
})
4、子窗口跳转到另一个子窗口的情况
在父窗口加载iframe时,打印日志。
- parent.html
function load() {
console.log('加载。。。');
}
从son.html跳转到daughter.html,再返回到son.html。打印日志如下:
子窗口每一次跳转都会使用iframe重新加载不同的html。所以也可以使用DOM节点修改是src来跳转,并且可以携带参数。如:
- daughter.html
window.parent.document.getElementById('if').src='/son.html?msg=xixi';
- son.html
let url = location.search; //获取url中"?"符后的字串
if(url.length>0) { //判断是否携带参数
let params = {};
if (url.indexOf('?') != -1) {
this.isShwoInput = true;
let str = url.substr(url.indexOf('?') + 1);
let strs = str.split('&');
for (let i = 0; i < strs.length; i++) {
params[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1]);
}
}
// return params;
console.log(params);
}
5、iframe的宽高适配子窗口
在iframe在load完html后,获取子窗口的宽高来决定iframe的宽高。
- parent.html
var scrollHeight = document.getElementById('if').contentWindow.document.body.scrollHeight;
var scrollWidth = document.getElementById('if').contentWindow.document.body.scrollWidth;
document.getElementById('if').width = scrollWidth;
document.getElementById('if').height = scrollHeight;
这里顺便说明下onload的触发时机:
onload函数的执行并不是我们通常所理解的浏览器构建完html页面对应的DOM树后立刻执行,而是要等到页面中所引用的图片等外部资源 完全下载完成后并且在浏览器中显示才执行。
6、源码
- parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Title</title>
<script>
var list_parent = new Array();
list_parent.push("刘备");
list_parent.push("关羽");
list_parent.push("张飞");
function parent_fun() {
return list_parent;
}
function load() {
console.log('加载。。。');
// 自适应子窗口的宽高
var scrollHeight = document.getElementById('if').contentWindow.document.body.scrollHeight;
var scrollWidth = document.getElementById('if').contentWindow.document.body.scrollWidth;
document.getElementById('if').width = scrollWidth;
document.getElementById('if').height = scrollHeight;
console.log(document.readyState); // Interactive. 可以接收到部分响应数据,网上说这个状态时,数据是只读的,但是我修改了数据,发现也是生效的
}
function get_son_var_fun() {
console.log('加载。。。');
// 获取子窗口变量和方法
console.log(document.getElementById('if').contentWindow.list_son);
document.getElementById('if').contentWindow.list_son.pop();
// 这是在父窗口中改变了子窗口的变量的值,并通知到父窗口。
document.getElementById('if').contentWindow.parent.postMessage({
msg: document.getElementById('if').contentWindow.list_son
},"*");
console.log(document.getElementById('if').contentWindow.son_fun());
console.log(document.readyState); // Interactive. 可以接收到部分响应数据,网上说这个状态时,数据是只读的,但是我修改了数据,发现也是生效的
}
function changeVar() {
list_parent.pop();
document.getElementById('if').contentWindow.postMessage({ // 参考:https://blog.csdn.net/it_java_shuai/article/details/109443125
msg: list_parent
},"*")
}
//父页面监听:
window.addEventListener("message", function(event){
console.log(event);
var data = event.data;
console.log("parent --- 监听到子窗口的变量的变化" + JSON.stringify(data));
})
</script>
</head>
<body>
<h1>我是父窗口</h1>
<!--
Iframe还未被加载完成就调用里面的方法或者变量,会报错,判断iframe是否被加载完成的方法有:
1、document.readyState=="complete"
2、onload事件(推荐)
-->
<button id="getVarAndFun" type="button" onclick="get_son_var_fun()">获取子窗口的变量和方法</button>
<button id="changeVar" type="button" onclick="changeVar()">改变父窗口的值</button>
<iframe id="if" name="if" scrolling="no" src="son.html" onload="load()"></iframe>
</body>
</html>
- son.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
html,body {
margin: 0;
padding: 0;
width: 100px;
height: 200px;
}
</style>
<script type="text/javascript">
var list_son = new Array();
list_son.push("曹操");
list_son.push("司马懿");
function son_fun() {
return list_son;
}
function getParentVar() {
// alert("getParentVar");
console.log(window.parent.list_parent);
}
function getParentFun() {
console.log(window.parent.parent_fun());
}
function load_son() {
let url = location.search; //获取url中"?"符后的字串
if(url.length>0) { //判断是否携带参数
let params = {};
if (url.indexOf('?') != -1) {
this.isShwoInput = true;
let str = url.substr(url.indexOf('?') + 1);
let strs = str.split('&');
for (let i = 0; i < strs.length; i++) {
params[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1]);
}
}
// return params;
console.log(params);
}
}
window.addEventListener("message",function(event){
var data =event.data;
console.log("son --- 监听到父窗口的变量的变化" + JSON.stringify(data));
});
</script>
<!--<body>-->
<body onload="load_son()">
<div id="sonid" style="background: green;">
<button id="getVar" type="button" onclick="getParentVar()">获取父窗口变量</button>
<button id="getFun" type="button" onclick="getParentFun()">获取父窗口方法</button>
<br>
<a href="daughter.html">跳转另一子窗口</a>
son
</div>
</body>
</html>
- daughter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
html,body {
margin: 0;
padding: 0;
width: 150px;
height: 200px;
}
</style>
<script>
function goback() {
// window.history.back();
window.parent.document.getElementById('if').src='son.html?msg=xixi';
}
window.addEventListener("message",function(event){
var data =event.data;
console.log("daughter 监听到父窗口的变量的变化--- " + JSON.stringify(data));
});
</script>
</head>
<body>
<div id="sonid" style="background: pink; width: 100px; height: 200px">
<button id="back" type="button" onclick="goback()">返回上一个窗口</button>
daughter
</div>
</body>
</html>
参考
blog.csdn.net/weixin_4404… blog.csdn.net/ios0213/art… blog.csdn.net/it_java_shu…