一、什么是iframe
HTML 内联框架元素 (<iframe>
) 表示嵌套的browsing context。它能够将另一个 HTML 。页面嵌入到当前页面中。
它最初由微软公司在Internet Explorer 3中推出。iframe
的出现主要是为了解决网站内嵌内容的安全隐患问题。在网站内嵌内容时,如果直接引用外部网站的资源,可能会存在跨域问题,这时候使用iframe
就可以解决这个问题,因为iframe
中的内容是被放在一个独立的HTML文档中,在这个文档中引用外部资源就不会存在跨域问题了。
然而,在那个网速很慢的年代,一些开发者通过这种方式把页面切分成不同的模块,从而优化整体的加载速度,但这样做会导致很大的开发与维护成本(微前端实现方式之一)。因此,虽然iframe
在某些情况下是有用的,但XHTML最后没有获得大规模的使用。
随着时间的推移,iframe
经历了更多的变化和改进。比如,它可以用于实现网页中的异步加载,提高用户体验。同时,它也支持各种属性和方法,例如src
、width
、height
等,使用户可以更方便地控制和管理嵌入的内容。
二、基础使用
iframe特性全解读
<iframe>
标签生成一个指定区域,在该区域中嵌入其他网页。它是一个容器元素,如果浏览器不支持<iframe>
,就会显示内部的子元素。
<iframe width="400px" height="400px" src="https://www.bookstack.cn/read/html-tutorial/spilt.1.docs-iframe.md">
<p><a href="https://www.bookstack.cn/read/html-tutorial/spilt.1.docs-iframe.md">基本用法-阮一峰</a></p>
</iframe>
上面的代码在当前页面嵌入了www.bookstack.cn/read/html-t… ,宽高都设置了400px。如果当前浏览器不支持iframe标签,则会显示链接。 整体来说iframe的支持性还是非常好的,所以内部内容不写也是可以的。
iframe的属性包括:
align
:规定如何根据周围的元素对齐此框架。border
:规定是否显示框架周围的边框。height
:规定iframe的高度。importance
:浏览器下载嵌入的网页的优先级,可以设置三个值。high
表示高优先级,low
表示低优先级,auto
表示由浏览器自行决定。longdesc
:定义一个页面,该页面包含有关iframe的较长描述。marginheight
:定义iframe的顶部和底部的边距。marginwidth
:定义iframe的左侧和右侧的边距。name
:规定iframe的名称。scrolling
:规定是否在iframe中显示滚动条。src
:规定在iframe中显示的文档的URL。sandbox
: 是限制嵌入内容所具有的权限,例如,可以阻止嵌入的页面执行脚本、提交表单或访问其他域名。这使得sandbox能够防止恶意内容对父页面进行攻击,如禁用插件、禁止其他浏览上下文的导航、禁止弹出窗口和模式对话框width
:规定iframe的宽度。
三、通信
获取子页面里的内容(同域)
主要两个API就是contentWindow
和contentDocument
。
iframe.contentWindow
获取iframe中的window对象。
iframe.contentDocument
获取iframe中的document对象。
<body class="main">
<h2>这是最顶层页面</h2>
<iframe src="./iframe1.html" frameborder="1" id="iframe1" width="600px" height="600px" name="iframe1"></iframe>
<script>
// 方式一:获取iframe的dom
var iframe1 = document.getElementsByTagName('iframe')[0];
// 方法二:获取iffame的dom
var iframe1 = window.frames['iframe1'];
console.log('iframe1==========', iframe1);
console.log('iframe1 window==========', iframe1.contentWindow);
console.log('iframe1 document==========', iframe1.contentDocument);
</script>
</body>
子页面中获取父级内容(同域)
在同域下,子叶main同样也能操作父页面内容。在iframe中,可以通过在window上挂载的几个API进行获取.
window.parent
获取上一级的window对象,如果还是iframe则是该iframe的window对象
window.top
获取最顶级容器的window对象,即,就是你打开页面的文档
window.self
返回自身window的引用。可以理解 window===window.self(脑残)
如下结果,灰色嵌套粉红色,粉红色嵌套红色。假设三层的window对象分别是window、window1和window2。那
window2.self === window2
window2.parent === window1
window2.top === window
postMessage(同域名、跨域)
MDN-window.postMessage 使用场景:子页面给主页面发信息。
// 子页面
window.parent?.postMessage?.('logout', '*');
// 主(父页面)
window.addEventListener('message', event => {
// console.log('receive message from iframe: ', event.data);
if (event.data === 'logout') {
logoutSystem();
}
});
路由传参数
可以将子页面需要的参数放到iframe的src上面,如下:
<iframe
src="**/center/iframe/sidebar/model"
width="100%"
frameborder="no"
></iframe>
四、子页面适配主页面样式
window.parent
子页面中判断window.parent属性的值是否存在,如果存在则表示为iframe嵌套,则修改样式
contentWindow?.document(同域)
在主页面中直接修改子页面样式。但在实践中,要求主页和子页面同域名,且需要一个定时任务来保证修改的准确性。
示例如下:
<template>
<iframe
id="iframe"
:src="iframeSrc"
width="100%"
frameborder="no"
@load="handleLoaded"
></iframe>
</template>
<script setup lang="ts">
import {ref, onUnmounted} from 'vue';
const iframeSrc = ref('http://baidu.com');
let interval = null;
function handleLoaded(event) {
const iframe: any = document.getElementById('iframe');
// 无法保证js执行的时候,子页面dom已经加载完成,所以使用了一个定时任务
timer = setInterval(() => {
const header = iframe.contentWindow?.document?.getElementsByClassName('main-header')?.[0];
if (header) {
clearInterval()
header.style.display = 'none';
}
}, 500);
}
onUnmounted(() => {
clearInterval(timer);
});
</script>
五、作用
广告
使用iframe来做广告的原因主要有以下几点:
- 避免广告代码对主页面的影响:通过将广告嵌入到页面中的iframe中,可以避免广告代码对主页面的影响,提高用户体验。
- 增加网页安全性:使用iframe嵌入广告内容,可以减少广告代码与主页面的交互,从而降低安全风险。
- 更好地控制广告展示:使用iframe来展示广告,可以更好地控制广告的展示效果,例如调整广告的布局、尺寸等。
- 提高广告点击率:由于iframe中的广告内容与主页面是分开的,因此用户在点击广告时,可以直接进入广告页面,从而提高广告的点击率。
多个产品同一个平台展示
多个应用在一个平台上进行展示。这儿的作用类似微前端。是我的一个具体的项目实践。具体改造还挺多的,今天不想写啦,等我想写的时候,再写一个iframe的实践吧。
六、后记
这个文章草稿还是一年前的,当时想的是每周写一篇文章,但是 但是 懒了,没有付出实际行动。