iframe学习
1.iframe
是什么?
a)iframe
是html
元素,用于在网页中内嵌另一个网页。
b)iframe
默认有一个宽高,存在边界。
c)iframe
是一个行内块级元素,可以通过display
修改。
2.iframe
元素属性有哪些?
a)src
: 指定内联网页的地址。
b)frameborder
: iframe
默认有个边界,可以设置frameborder
为0
清除边界。frameborder
已过时,最好使用css
属性来修改边框。
c)width
,height
: 控制iframe
的宽高。
d)name
: 框架的名称。
e)scrolling: 是否可滚动,
yes ,
no,
auto。
3.iframe
互相操作
每个iframe
里都有 各自维护自己的 全局window
对象。
3.1父级操作子iframe
在父级使用iframe.contentWindow获取子iframe的window对象,根据window对象进而可以获取子iframe的document对象,根据document对象又可以对html元素进行操作。示例如下:
js
var iframe = document.getElementById("myrame"); //获取iframe标签
var iwindow = iframe.contentWindow; //获取iframe的window对象
var idoc = iwindow.document; //获取iframe的document对象
console.log(idoc.documentElement); //获取iframe的html
3.2子iframe操作父级
在子iframe
想要操作父元素的iframe
,直接使用子元素的window.parent
来获取父级元素的window
对象,从而获取document
来操作dom
。示例如下:
js
window.parent.document.getElementById("auditDate").value;
4.iframe
之间的通信
4.1不跨域
a)不跨域情况下,父组件向iframe
子组件传值(或父组件中定义一个属性,iframe子组件可以获取到父组件的属性)
方法一:子组件使用parent可以获取到父组件的window对象,进而获取父组件定义的属性;
js
//父组件定义fatherData
let fatherData = '父元素数据';
//子iframe获取fatherData
console.log(parent.fatherData);
方法二:父组件 通过向iframe的contentWindow添加属性,子组件需要时通过Window[属性名]获取父元素传递的数据;(个人理解,父组件通过contentWindow获取到子iframe的window对象,直接在子iframe的window对象上定义属性,那么子iframe通过自己的window对象就能获取到父组件定义的属性了)
js
//父组件定义fatherData
let fatherData = '父元素数据';
//父组件向子iframe的contentWindow添加属性
let iframe1 = document.getElementById('iframe1');
iframe1.contentWindow.fatherData = fatherData;
//子iframe获取fatherData
(() => {
console.log(window.fatherData);
})()
方法三:子组件定义函数fn, 父组件 通过iframe的contentWindow获取到子组件fn,并通过fn传值到iframe子组件;(个人理解,父组件通过contentWindow获取到子iframe的window对象,相当于父组件在子组件里的权利和子组件一样,可以使用子组件里的任何方法或属性,父组件调用子组件里的方法和子组件调用自己的方法无差别)
js
//父组件定义fatherData
let fatherData = '父元素数据';
//子Iframe定义方法
function setIframe1(data) {
console.log(data);
}
//父组件通过子iframe的contentWindow调用子iframe定义的方法
let iframe1 = document.getElementById('iframe1');
iframe1.contentWindow.setIframe1(fatherData);
b)iframe
子组件向父组件传值。
父元素定义函数getChild
并通过向iframe
的contentWindow
添加getChild
方法,子组件通过Window.getChild();
传值给父组件;
js
//父组件定义函数
function getChild(data) {
console.log('获取到子组件数据', data);
}
//父组件向`iframe`的`contentWindow`添加`getChild`方法
let iframe1 = document.getElementById('iframe1');
iframe1.contentWindow.getChild = getChild();
//子组件调用
(() => {
window.getChild('hhh');
})()
4.2跨域
方法一:利用location.hash
,父组件给子组件iframe
标签的src
属性链接后面添加#
,子组件通过location.hash
获取父组件数据,从而达到父组件操作子组件。
html
//父组件
<iframe id="iframe1" src="xxxx#msg=111" width="" height="" frameborder="0" scrolling="no"></iframe>
js
//子iframe
console.log('location.hash', location.hash);
方法二:使用postMessage
实现跨域通信。postMessage方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
js
//语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
//otherWindow:发送消息的窗口
//message:将要发送到其他window的数据。
//targetOrigin:指定那些窗口能接收到消息事件,其值可以是字符串 "*" 表示无限制,或者是一个URI。
//transfer:是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送方将不再保留所有权。
postMessage方法被调用时,会在所有页面脚本执行完毕之后像目标窗口派发一个 MessageEvent 消息,该MessageEvent消息有四个属性需要注意:
type:表示该message的类型
data:为 postMessage 的第一个参数
origin:表示调用postMessage方法窗口的源
source:记录调用postMessage方法的窗口对象
js
//父组件定义fatherData
let fatherData = '父元素数据';
//父组件发送消息给子iframe
(() => {
iframe1.contentWindow.postMessage(fatherData,
"http://xxxx/iframe1.html")
})()
//子iframe监听消息
window.addEventListener('message', function(event) {
console.log('event', event);
}, false);
5.注意
获取子元素的document
时要确保子元素所有dom
元素已经挂载完毕,因此在原生的写法时,必须写在window
的onload
事件中。