iframe 隐藏滚动条、高度自适应及父子页面通信

用户头像
Verlime
关注
发布于: 2020 年 07 月 21 日
iframe 隐藏滚动条、高度自适应及父子页面通信

HTML 标签 iframe 用于在当前页面中嵌套另外一个页面,一般我们需要在页面中嵌入一些第三方的视频、地图、广告等展示资源时就会用到它。



但在使用 iframe 时往往会遇到一些问题,比如滚动条问题、高度自适应问题以及浏览器同源策略引起的问题等,这里我们就来看一下该如何解决。

隐藏滚动条

由于 iframe 默认是带滚动条和边框的,某些场景下为了提高体验一般会把边框和滚动条去掉,并且使 iframe 的高度等于被嵌套页面的高度。



对于边框的问题,直接使用 frameborder="0" 就可以去掉,例如:



<iframe src="http://www.baidu.com" frameborder="0"></iframe>



对于隐藏滚动条,可以使用 scrolling="no" 来处理,例如:

<iframe width="100%" height="200" src="http://www.qq.com" frameborder="0" scrolling="no"></iframe>



另外,有些资料里提到可以使用 CSS 的方法 iframe {overflow: hidden;} 来处理,但是经测试并没有生效,虽然 iframe 的 scrolling 属性在 HTML5 标准里已经废弃,但目前貌似只能用这个属性来处理。

高度自适应

由于去掉了滚动条,被嵌套的页面已经不能够滚动,这个时候就需要使 iframe 的高度等于被嵌套页面的高度,这样才能够使被嵌套的页面内容能够完整的显示。



那么重点就在于如何获取 iframe 嵌套页面的高度,首先我们可以通过 window.frames[iframeName] 的方式获取到 iframe 元素。



<iframe width="100%" height="200" id="my-iframe" name="myiframe" src="./demo1-child.html" frameborder="0" scrolling="no"></iframe>



这个给 iframe 设置了一个 id 为 myIframe,然后通过如下方式获取并设置 iframe 的高度:



var myIframe = document.querySelector('#my-iframe');
myIframe.onload = function() {
var doc = window.frames['myiframe'].document;
myIframe.style.height = doc.documentElement.scrollHeight +'px';
};



当然还可以通过 contentWindow.document 或者 contentDocument 来获取 iframe 页面的 document 对象,注意,contentDocument 在 IE8 以下不支持,示例如下:



var myIframe = document.querySelector('#myIframe');
myIframe.onload = function() {
var doc = myIframe.contentDocument || myIframe.contentWindow.document;
myIframe.style.height = doc.documentElement.scrollHeight + 'px';
};



父子页面通信

需要注意的是由于浏览器的同源策略,不能够直接获取跨域页面的内容,postMessage 可以作为其中的一种解决办法,这就需要父子页面互相配合来实现了。



使用 postMessage 的一个示例如下(HTML 代码省略):

父页面



在父页面点击按钮时,会向子页面发送一条消息,并且在父页面也监听了 message 事件,用于接收子页面发送过来的消息。



var myIframe = document.querySelector('#myIframe');
var btn = document.querySelector('#btn');
btn.onclick = function() {
var data = {message:"hello world!"}
myIframe.contentWindow.postMessage(JSON.stringify(data), 'http://127.0.0.1:60608');
}
window.addEventListener('message', function(event) {
console.log(event.origin);
// http://127.0.0.1:60608
console.log(JSON.parse(event.data));
// {message: "from child!"}
})



子页面



在子页面里监听 message 事件,当接收到父页面传来的消息时,再向父页面发送消息。



window.addEventListener('message', function(event) {
console.log(event.origin);
// http://127.0.0.1:60608
console.log(JSON.parse(event.data));
// {message: "hello world!"}
window.parent.postMessage(JSON.stringify({message: "from child!"}), 'http://127.0.0.1:60608');
})



另外需要注意在使用 https 访问的页面中,iframe 嵌套的页面也必须是支持 https 的,否则嵌套的页面无法加载。

参考资料



Photo by Buchen WANG on Unsplash

发布于: 2020 年 07 月 21 日 阅读数: 97
用户头像

Verlime

关注

一个前端工程师 2018.01.01 加入

每天进步一点点ヽ(•̀ω•́ )ゝ

评论

发布
暂无评论
iframe 隐藏滚动条、高度自适应及父子页面通信