跳到主要内容
版本:1.0

iframe

信息

微服务实现、框架配置

1.简介

HTML 内联框架元素 <iframe> 表示嵌套的 browsing context。它能够将另一个 HTML 页面嵌入到当前页面中。

<iframe
//用作 <a> 标签与 <form> 标签的 target 属性值,也可以用作 <input> 标签和 <button> 标签的 formtarget 属性值,还可以用作 window.open() 方法的 windowName 参数值。
name="test"
id="inlineFrameExample"
title="Inline Frame Example"
width="300"
height="200"
src="https://example.org"
allowfullscreen="true"
referrerpolicy="no-referrer"
></iframe>

2.事件:onload

<iframe
onload="onload"
src="https://zingy-fudge-57d344.netlify.app/docs/%E9%97%AE%E9%A2%98%E9%9B%86%E5%90%88/img"
scrolling="auto"
style={{ border: "1px solid" }}
>
<p>Your browser does not support iframes.</p>
</iframe>
iframe 页

引申:父页面单方面调用子组件绑定事件
<iframe
id="iframe"
src={"xxxx"}
frameborder="0"
onLoad={() => {
let doc = document
.getElementById("iframe")
.contentWindow.document.getElementsByTagName("body")[0];
let imgs = doc.children[0];
imgs.setAttribute("onclick", "javascript:window.parent.downLoadFile()");
imgs.alt = "下载文件";
imgs.title = "下载文件";
//实现文件下载功能
window.downLoadFile = function () {
let src = "xxx";
let form = document.createElement("form");
form.action = src;
document.getElementsByTagName("body")[0].appendChild(form);
form.submit();
};
}}
/>

3.同域下父子页面的通信

parent
<html>
<head>
<script type="text/javascript">
function say() {
alert("parent.html");
}
function callChild() {
myFrame.window.say();
myFrame.window.document.getElementById("button").value = "调用结束";
}
</script>
</head>
<body>
<input
id="button"
type="button"
value="调用child.html中的函数say()"
onclick="callChild()"
/>
<iframe name="myFrame" src="child.html"></iframe>
</body>
</html>
child
<html>
<head>
<script type="text/javascript">
function say(){
alert("child.html");
}
function callParent(){
parent.say();
parent.window.document.getElementById("button").value="调用结束";
}
</script>
</head>
<body>
<input id="button" type="button" value="调用parent.html中的say()函数" onclick="callParent()"/>
</body>
</html>

父页面调用子页面方法:FrameName.window.childMethod();

子页面调用父页面方法:parent.window.parentMethod();

注意

**注意事项**

要确保在 iframe 加载完成后再进行操作,如果 iframe 还未加载完成就开始调用里面的方法或变量,会产生错误。判断 iframe 是否加载完成有两种方法:

  1. iframe 上用 onload 事件

  2. document.readyState=="complete"来判断


监听自定义事件

parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<h2>嵌入b页面:</h2>
<iframe id="b_iframe" src="b.html"></iframe>
</body>
<script type="text/javascript">
var adata = "huzhen120";
var b_win = document.getElementById("b_iframe").contentWindow;
b_win.addEventListener("tReady", function (e) {
var msg = e.detail.msg;
console.log("getmsg:" + msg);
});
</script>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<span id="bspan" style="color:red;">我是嵌入的b页面</span>
</body>
<script type="text/javascript">
var data = "huzhenv5"; // b页面的数据
// 测试触发
setTimeout(
function () {
// 1,创建事件对象
var bEvent = new CustomEvent("tReady", {
detail: {
msg: "2000ms ok",
doc: document,
},
bubbles: true, // 是否冒泡
cancelable: true, // 是否可以取消事件的默认行为
});
window.dispatchEvent(bEvent);
}.bind(this),
2000
);
</script>
</html>

4.跨域父子页面通信方法

如果 iframe 所链接的是外部页面,因为安全机制就不能使用同域名下的通信方式了。

父页面向子页面传递数据

实现的技巧是利用 location 对象的 hash 值,通过它传递通信数据。在父页面设置 iframe 的 src 后面多加个 data 字符串,然后在子页面中通过某种方式能即时的获取到这儿的 data 就可以了,例如:

  1. 在子页面中通过 setInterval 方法设置定时器,监听 location.href 的变化即可获得上面的 data 信息

  2. 然后子页面根据这个 data 信息进行相应的逻辑处理

子页面向父页面传递数据

实现技巧就是利用一个代理 iframe,它嵌入到子页面中,并且和父页面必须保持是同域,然后通过它充分利用上面第一种通信方式的实现原理就把子页面的数据传递给代理 iframe,然后由于代理的 iframe 和主页面是同域的,所以主页面就可以利用同域的方式获取到这些数据。使用 window.top 或者 window.parent.parent 获取浏览器最顶层 window 对象的引用。

5.react 的 iframe hook