Bootstrap

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

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

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

隐藏滚动条

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

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

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

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

高度自适应

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

那么重点就在于如何获取 iframe 嵌套页面的高度,首先我们可以通过 的方式获取到 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';
};

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

var myIframe = document.querySelector('#myIframe');

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

父子页面通信

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

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

父页面

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

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!"}
})

子页面

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

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');
})

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

参考资料

Photo by Buchen WANG on Unsplash