如何用css影响iframe中的内容?
前言
iframe
是一种外网页上显示外部内容的非常方便的方式。但是,如果说这个iframe
中的样式存在你不满意的地方,你如果想通过简单的在父容器上添加css
规则来改变它,这很明显是无效的,在本文中,我们将来尝试着如何通过 JavaScript
将 自定义的 css
注入 iframe
中
通过 contentDocument 注入 style
我们可以通过 contentDocument
来使得 iframe
中的内容通过 HTML
对象进行返回,具体可以先获取到 iframe
的 DOM
对象,然后通过上面的 contentDocument
属性来获取 iframe
的 document
,值得注意的是,在部分浏览器当中不支持这个属性,但是可以通过 contentWindow
属性来获取 window
对象,然后我们可以再通过 window.document
达到一样的效果。
因为我们需要获取到元素,所以需要把逻辑都放在元素载入完成以后也就是 window.onload
当中
在获取到 document
对象之后,我们就可以通过修改 innerHTML
的方式来注入 style
标签,这样就能够做到修改 iframe
中的样式,具体的兼容代码如下:
window.onload = function(){
let myIframe = document. getElementById('myIframe');
let doc = (myIframe.contentDocument || myIframe.contentWindow)
if (doc.document)doc=doc.document;
doc.body.innerHTML = doc.body.innerHTML + '<style>body{color: blue;}</style>'
}
动态获取css文件
fetch 获取 css 文件文本
上面的写法可能你会觉得太麻烦了 '<style>body{color: blue;}</style>'
这样来写样式文件很不符合正常人的写法。
我们可以通过 fetch
的方式来获取 css
文件,假如我就在同级目录下写入了一个 css
样式,就可以这样子来获取它。
/* main.css */
body {
font-size: 40px;
}
动态获取 css
:
async function setCss () {
const baseStyle = await fetch("./main.css").then(res => res.text())
console.log("🚀 ~ file: index.html:33 ~ setCss ~ baseStyle:", baseStyle)
}
setCss()
成功获取到文件当中的内容,然后我们就可以把内容作为字符串拼接到 style
当中去。
window.onload = function () {
let myIframe = document.getElementById('myIframe');
let doc = (myIframe.contentDocument || myIframe.contentWindow)
if (doc.document) doc = doc.document;
async function setCss () {
const baseStyle = await fetch("./main.css").then(res => res.text())
doc.body.innerHTML = doc.body.innerHTML + `<style>${baseStyle}</style>`
}
setCss()
}
link 标签注入
除了上面的通过 fetch
方式获取 css
文本,我们还可以通过动态创建 link
标签的方式来代替上面的修改 body.innerHTML
的过程,我们可以直接注入 link
标签。
window.onload = function () {
let myIframe = document.getElementById('myIframe');
let doc = (myIframe.contentDocument || myIframe.contentWindow)
if (doc.document) doc = doc.document;
let link = document.createElement('link')
link.href = 'main.css'
link.rel = 'stylesheet'
link.type = 'text/css'
console.log(link);
doc.head.appendChild(link)
}
但是这种方式的限制在于,你 link
标签的 href
属性直接决定了子项目要去哪里获取这个 css
文件,这可能会导致路径错误的问题。比方说在同一个目录下的两个文件我这样引入是没有问题的。
但是一旦我用一个文件夹来保存子文件,不让他们处于同一目录下
这样就会导致 css
获取失败,我们从浏览器的元素审查中也能够看到
子元素的标签只会去获取你写入 herf
的内容,所以这就需要了解子所在的目录位置
注意
注意上述的方法都只能用于在引用同源的 iframe
内容的时候,对于跨域内容,你只能通过 contentWindow
来获取 window
对象,contentDocument
将会返回一个 null
对象(这里在不同浏览器可能表现不同,本文主要是以谷歌浏览器作为例子)。并且在你想要访问 window
上的属性的时候,控制台将会抛出跨域的报错。
转载自:https://juejin.cn/post/7281165909405384738