如何控制iframe
中身体元素的背景图像和颜色?注意,嵌入的body元素有一个类,iframe
是我的站点的一部分。
我需要这个的原因是,我的网站有一个黑色背景分配给正文,然后有一个白色背景分配给包含文本的div。所见即所得编辑器在编辑时使用iframe
嵌入内容,但它不包括div,因此文本很难阅读。
iframe
在编辑器中的主体有一个在其他地方没有使用的类,所以我假设它被放在那里,这样类似的问题就可以得到解决。但是,当我将样式应用于class.body
时,它们不会覆盖应用于主体的样式。奇怪的是,这些风格确实出现在Firebug中,所以我不知道发生了什么!
感谢
更新-我尝试了@mikeq的解决方案,将样式添加到作为主体类的类中。这在添加到主页的样式表时不起作用,但在添加Firebug时起作用。我认为这是因为Firebug应用于页面上的所有元素,而CSS不应用于iframe中。这是否意味着在用JavaScript加载窗口后添加css就可以了?
以下仅在iframe内容来自同一父域时有效
以下代码适用于我。在Chrome和IE8上进行了测试。内部iframe引用的页面与父页面位于同一域中。
在这种特殊情况下,我将在内部iframe中隐藏一个具有特定类的元素。
基本上,您只需将style
元素附加到框架中加载的文档的头部:
frame.addEventListener("load", ev => {
const new_style_element = document.createElement("style");
new_style_element.textContent = ".my-class { display: none; }"
ev.target.contentDocument.head.appendChild(new_style_element);
});
您也可以使用link
元素来引用样式表资源,而不是style
。
iframe是页面中的一个"洞",在其中显示另一个网页。iframe的内容不是父页面的任何形状或形式。
正如其他人所说,你的选择是:
- 为正在iframe中加载的文件提供必要的CSS
- 如果iframe中的文件与您的父级文件来自同一个域,那么您可以从父级访问iframe内文档的DOM
您不能更改iframe中显示的页面的样式,除非您有直接访问权限,并因此拥有源html和/或css文件的所有权。
这是为了停止XSS(跨站点脚本)
此代码使用普通JavaScript。它创建了一个新的<style>
元素。它将该元素的文本内容设置为包含新CSS的字符串。它将该元素直接附加到iframe文档的头中。
但是,请记住,访问从另一个来源加载的文档的元素是不允许的(出于安全原因)——当从嵌入框架的页面的浏览上下文尝试时,iframe
元素的contentDocument
将评估为null。
var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
'body {' +
' background-color: some-color;' +
' background-image: some-image;' +
'}'
;
iframe.contentDocument.head.appendChild(style);
覆盖另一个域iframe
CSS
通过使用SimpleSam5的部分答案,我通过Tawk的一些聊天iframe实现了这一点(它们的自定义界面很好,但我需要进一步的自定义)。
在这个显示在移动设备上的特定iframe中,我需要隐藏默认图标并放置一个背景图像。我做了以下事情:
Tawk_API.onLoad = function() {
// without a specific API, you may try a similar load function
// perhaps with a setTimeout to ensure the iframe's content is fully loaded
$('#mtawkchat-minified-iframe-element').
contents().find("head").append(
$("<style type='text/css'>"+
"#tawkchat-status-text-container {"+
"background: url(https://example.net/img/my_mobile_bg.png) no-repeat center center blue;"+
"background-size: 100%;"+
"} "+
"#tawkchat-status-icon {display:none} </style>")
);
};
我不拥有任何Tawk的域名,这对我很有效,因此即使它不是来自同一个父域名,你也可以这样做(尽管Jeremy Becker对Sam的回答发表了评论)。
iframe
有另一个作用域,因此您无法访问它以进行样式设置或使用javascript更改其内容。
这基本上是"另一页"。
你唯一能做的就是编辑自己的CSS,因为有了全局CSS你什么都做不了。
如果您同时拥有
这里的技巧是给你的身体分配一个全局css变量,用新颜色监听消息,然后在收到消息后更改全局css变量。
我使用的是angular,但它应该与纯javascript一起使用
我的用例是在保存之前向用户展示颜色变化将如何影响iframe中的网站
域A
@ViewChildren('iframeContainer') iframeContainer: QueryList<ElementRef>
sendDataToIframe(
data = {
type: 'colorChange',
colors: {primary: '#000', secondary: '#fff'},
},
): void {
if (this.targetUrl)
this.iframeContainer.first.nativeElement.contentWindow.postMessage(data) // You may use document.getElementById('iframeContainer') instead
}
域B
acceptedEditOrigins = [
'https://my.origine.ccom', // Be sur to have a correct origin, to avoid xss injecto: https://en.wikipedia.org/wiki/Cross-site_scripting
]
constructor() {
// Listen to message
window.addEventListener('message', (event) => this.receiveMessage(event), false)
}
receiveMessage(event: MessageEvent) {
if (this.acceptedEditOrigins.includes(event.origin))
switch (event.data.type) {
case 'colorChange': {
this.setWebsiteConfigColor(event.data.colors)
}
}
}
setWebsiteConfigColor(colors: WebsiteConfigColors) {
if (colors) {
const root = document.documentElement
for (const [key, value] of Object.entries(colors)) {
root.style.setProperty(`--${key}`, value) // --primary: #000, --secondary: #fff
}
}
}
body {
background-color: var(--primary);
}
如果您可以控制承载iframe的页面和iframe所在的页面,则可以向iframe传递查询参数。。。
下面是一个根据托管站点是否是移动的向iframe添加类的示例。。。
添加iFrame:
var isMobile=$("mobile").length; //detect if page is mobile
var iFrameUrl ="https://myiframesite/?isMobile=" + isMobile;
$(body).append("<div id='wrapper'><iframe src=''></iframe></div>");
$("#wrapper iframe").attr("src", iFrameUrl );
iFrame内部:
//add mobile class if needed
var url = new URL(window.location.href);
var isMobile = url.searchParams.get("isMobile");
if(isMobile == "1") {
$("body").addClass("mobile");
}
只需一个iframe,您就可以执行以下操作:
document.querySelector('iframe').contentDocument.body.style.backgroundColor = '#1e1e2d';
如果您正在处理多个iframe:
document.querySelectorAll('iframe').forEach((iframe) => {
iframe.contentDocument.body.style.backgroundColor = '#1e1e2d';
});
也许现在已经更改了,但我使用了一个单独的样式表来处理这个元素:
.feedEkList iframe
{
max-width: 435px!important;
width: 435px!important;
height: 320px!important;
}
为iframe页面的主体提供一个ID(如果愿意,也可以是类)
<html>
<head></head>
<body id="myId">
</body>
</html>
然后,同样在iframe的页面中,为CSS 中的背景指定一个背景
#myId {
background-color: white;
}