#1 楼
编辑:除非设置了适当的CORS标头,否则跨域工作。这里有两件事:iframe块的样式和iframe中嵌入的页面的样式。您可以按照以下常规方法设置iframe块的样式:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
必须通过将iframe中嵌入的页面包含在子页面中来进行设置:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
或者可以使用Javascript从父页面加载它:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
评论
请注意,在我看来,以前发布的某些示例现在对html5无效。您可以按以下方式访问框架的内容:document.getElementById(“ myframe”)。contentDocument。嵌入CSS似乎仍然对我不起作用。
–雷诺·林德克(Rehno Lindeque)
2011-2-2在19:54
链接只能出现在HEAD中
– Knu
2011年5月23日19:05
仅在完成... document.head.appendChild(cssLink)-Firefox和Safari时为我工作。
– mojuba
2011-09-26 12:47
这实际上可以跨域工作吗?我认为不会。
–西蒙东
2011年11月4日,0:52
只是没有其他人必须对其进行测试才能发现:正确,它不能跨域工作。在执行frame ['name']后,您立即获得“不安全的JavaScript尝试从具有URL blah的框架访问具有URL blah的框架。域,协议和端口必须匹配。”
–凯文
2011-11-27 17:37
#2 楼
我在Google日历中遇到了这个问题。我想在较暗的背景上设置样式并更改字体。幸运的是,嵌入代码中的URL没有直接访问限制,因此通过使用PHP函数
file_get_contents
,可以获取页面上的所有内容。除了调用Google URL,还可以调用服务器上的php文件,例如。
google.php
,其中将包含原始内容并进行了修改: $content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
将路径添加到您的样式表:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(这会将样式表放置在
head
结束标记之前。 )以原始URL形式指定基本URL,以防css和js被相对调用:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
最终的
google.php
文件应如下所示: <?php
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
echo $content;
,然后将
iframe
嵌入代码更改为: <iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
祝你好运! br />
评论
如果需要,可以根据定义将其称为骇客入侵。但是您没有提供任何更好的解决方案...该解决方案不是损害Google服务或欺骗人们以利用他们的弱点的方法。
– SequenceDigitale.com
2014年8月12日下午16:58
我会想办法使此解决方案与Google文档一起使用。它会引发各种JavaScript错误。 “未捕获的TypeError:无法读取未定义的属性'a'”
– deweydb
2014年8月19日23:52
没关系,我知道了,在这里发布了解决方案:stackoverflow.com/questions/25395279/…
– deweydb
2014年8月20日,1:12
@ChrisHoughton仅供参考,基本上不是。但是,这可能会使整个iframe变得毫无意义(例如,使用iframe的一个原因是出于安全目的,例如使用卡付款,如果您按照此处的建议进行操作,很可能会导致自己出现问题)。
–阿拉斯泰
2015年2月5日在16:31
这样,您始终可以将日历作为未登录用户使用。使用普通的html iframe,如果用户登录google,则他们会看到他们自己的个人日历,但是由于您的PHP代码无法得知用户的Google会话ID,因此无法获取他们的个人日历。
–bdsl
17年1月10日在15:10
#3 楼
如果iframe的内容不完全在您的控制之下,或者您想从不同样式的不同页面访问内容,则可以尝试使用JavaScript进行操作。var frm = frames['frame'].document;
var otherhead = frm.getElementsByTagName("head")[0];
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "style.css");
otherhead.appendChild(link);
请注意,取决于您使用的浏览器,此方法可能仅适用于来自同一域的页面。
评论
可能值得注意的是,如果页面位于不同的域上,则相同的原始策略将停止此工作。
– ConroyP
08年10月20日9:00
以同样的思路,但更简洁:
–保护者一
16-09-26在12:35
甚至Firefox也变了CORS
–user985399
19/12/25在8:04
片段
#4 楼
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
评论
@deweydb我专门用于跨域iframe。但我只能请您原谅!
–拉米·萨里丁(Rami Sarieddine)
2014年8月22日13:49
@ramie,您是否在多个浏览器中进行了测试?大多数浏览器都抛出安全错误。
– deweydb
2014年8月22日在20:56
我以前见过这个想法,但是添加了一个链接来归档其真正出色和专业的内容... +上
– J.Tural
2015年12月24日9:24
#5 楼
这是如何直接应用CSS代码而不使用<link>
加载额外的样式表的方法。 var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
这会将横幅广告隐藏在iframe页面中。谢谢您的建议!
评论
是否需要ID为iframe的iframe?
–杰里米
13年11月22日在19:18
@jmalais只需将#iframe替换为#
– Zeb McCorkle
14年8月13日在19:01
这似乎不适用于我。我要编辑的iframe在dom中也没有直接位于其下方的头。那么这是否意味着我需要访问html文档的头部,还是jquery find函数应该能够自己完成的事情?
– David A. French
17年11月29日在4:04
检查了控制台,由于域不匹配,它似乎已被阻止访问iframe内容。我正在使用chrome,目前在本地托管我的开发环境。
– David A. French
17年11月29日在4:14
未捕获的DOMException:阻止了具有原始点的帧,这给了我这个错误
–priyanka patel
19/12/17在11:10
#6 楼
大多数浏览器普遍将iframe视为不同的HTML页面。如果要将相同的样式表应用于iframe的内容,只需从其中使用的页面引用它即可。评论
@hangry但是...如何?
–神的孩子
18年1月17日在17:45
在iframe中再次包含CSS文件
–mmoreram
10月1日7:11
#7 楼
如hangy所说,如果您在iframe中控制页面,最简单的方法是创建具有通用样式的共享CSS文件,然后只需从html页面链接到它即可。否则,您不太可能将能够从iframe中的外部页面动态更改页面的样式。这是因为由于可能滥用欺骗和其他黑客,浏览器加强了跨框架dom脚本的安全性。
本教程通常可以为您提供有关iframe脚本编写的更多信息。关于跨框架脚本从IE角度解释了安全限制。
#8 楼
上面的内容进行了一些改动:var cssLink = document.createElement("link")
cssLink.href = "pFstylesEditor.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
//Instead of this
//frames['frame1'].document.body.appendChild(cssLink);
//Do this
var doc=document.getElementById("edit").contentWindow.document;
//If you are doing any dynamic writing do that first
doc.open();
doc.write(myData);
doc.close();
//Then append child
doc.body.appendChild(cssLink);
至少在ff3和ie8上可以正常工作
评论
什么是myData,它来自哪里
–提格伦
2010-12-10在0:25
@Tigran用于动态数据
– Aakash
16-09-13在6:04
#9 楼
以下对我有用。var iframe = top.frames[name].document;
var css = '' +
'<style type="text/css">' +
'body{margin:0;padding:0;background:transparent}' +
'</style>';
iframe.open();
iframe.write(css);
iframe.close();
评论
错误:未被捕获的TypeError:无法读取未定义的属性“打开”
– KingRider
16-09-19在18:05
#10 楼
评论
应该注意的是,如果页面的内容以任何方式都是动态的,则此解决方案将不起作用。
– nickdnk
16年4月15日在12:48
#11 楼
扩展上述jQuery解决方案以应对加载框架内容中的任何延迟。 $('iframe').each(function(){
function injectCSS(){
$iframe.contents().find('head').append(
$('<link/>', { rel: 'stylesheet', href: 'iframe.css', type: 'text/css' })
);
}
var $iframe = $(this);
$iframe.on('load', injectCSS);
injectCSS();
});
评论
“ $ this”必须是“ $(this)”才能起作用。不错,当它做:)
–h.coates
2014年7月7日在7:34
#12 楼
我的精简版:<script type="text/javascript">
$(window).load(function () {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
});
</script>
但是,有时
iframe
在窗口加载时尚未准备好,因此需要使用计时器。即用型代码(带有计时器):
<script type="text/javascript">
var frameListener;
$(window).load(function () {
frameListener = setInterval("frameLoaded()", 50);
});
function frameLoaded() {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
clearInterval(frameListener); // stop the listener
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
}
</script>
...和jQuery链接:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
#13 楼
使用可以尝试以下方法:$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
评论
如果您的iframe来自不同的来源,则CORS机制将不允许这种解决方法。
–安德森先生
17年11月9日在13:14
如果iframe网址在所有位置都启用了CORS,该怎么办?
– adrhc
18-10-25在20:35
#14 楼
这里的其他答案似乎使用jQuery和CSS链接。此代码使用普通JavaScript。它将创建一个新的
<style>
元素。它将该元素的文本内容设置为包含新CSS的字符串。并将该元素直接附加到iframe文档的头部。 var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
'.some-class-name {' +
' some-style-name: some-value;' +
'}'
;
iframe.contentDocument.head.appendChild(style);
#15 楼
当您说“ doc.open()”时,它意味着您可以在iframe中编写任何HTML标签,因此您应该为HTML页面编写所有基本标签,如果要在iframe头中包含CSS链接,只需编写一个内嵌CSS链接的iframe。我举一个例子:doc.open();
doc.write('<!DOCTYPE html><html><head><meta charset="utf-8"/><meta http-quiv="Content-Type" content="text/html; charset=utf-8"/><title>Print Frame</title><link rel="stylesheet" type="text/css" href="/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');
doc.close();
#16 楼
由于针对相同的域编写了许多答案,因此我将在跨域中编写操作方法。首先,您需要了解Post Message API。我们需要一个Messenger来在两个窗口之间进行通信。
这里是我创建的Messenger。
/**
* Creates a messenger between two windows
* which have two different domains
*/
class CrossMessenger {
/**
*
* @param {object} otherWindow - window object of the other
* @param {string} targetDomain - domain of the other window
* @param {object} eventHandlers - all the event names and handlers
*/
constructor(otherWindow, targetDomain, eventHandlers = {}) {
this.otherWindow = otherWindow;
this.targetDomain = targetDomain;
this.eventHandlers = eventHandlers;
window.addEventListener("message", (e) => this.receive.call(this, e));
}
post(event, data) {
try {
// data obj should have event name
var json = JSON.stringify({
event,
data
});
this.otherWindow.postMessage(json, this.targetDomain);
} catch (e) {}
}
receive(e) {
var json;
try {
json = JSON.parse(e.data ? e.data : "{}");
} catch (e) {
return;
}
var eventName = json.event,
data = json.data;
if (e.origin !== this.targetDomain)
return;
if (typeof this.eventHandlers[eventName] === "function")
this.eventHandlers[eventName](data);
}
}
在两个窗口中进行通信可以解决您的问题。
在主窗口中,
var msger = new CrossMessenger(iframe.contentWindow, "https://iframe.s.domain");
var cssContent = Array.prototype.map.call(yourCSSElement.sheet.cssRules, css_text).join('\n');
msger.post("cssContent", {
css: cssContent
})
然后从iframe接收事件。
在iframe中:
var msger = new CrossMessenger(window.parent, "https://parent.window.domain", {
cssContent: (data) => {
var cssElem = document.createElement("style");
cssElem.innerHTML = data.css;
document.head.appendChild(cssElem);
}
})
有关更多详细信息,请参见完整的Javascript和iframe教程。
#17 楼
您将无法以这种方式设置iframe的内容样式。我的建议是使用服务器端脚本(PHP,ASP或Perl脚本)或查找将提要转换为JavaScript代码的在线服务。唯一的其他方法是可以在服务器端包含。评论
当您说无法做某事时要小心,而实际上却很难
– Lathan
2010-10-12 14:19
#18 楼
如果您有权访问iframe页面,并且仅当通过iframe在页面上加载该页面时希望在其上应用其他CSS,那么我在这里找到了针对此类情况的解决方案即使iframe正在加载其他域
检查有关
postMessage()
的信息计划是,将css作为消息发送给iframe,例如
iframenode.postMessage('h2{color:red;}','*');
*
将发送此消息,而不管它在iframe中的域是什么,并在iframe中接收该消息并将接收到的消息(CSS)添加到该文档头。
添加到iframe页面中的代码
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
#19 楼
我认为最简单的方法是在与iframe相同的位置添加另一个div,然后将其
z-index
设置为比iframe容器大,因此您可以轻松地设置自己的div的样式。如果您需要单击它,只需在自己的div上使用pointer-events:none
,这样iframe就可以在您需要单击它的情况下工作了;)我希望它会对某人有所帮助;)
#20 楼
我找到了另一个解决方案,将样式放在这样的主html中<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
,然后在iframe中执行此操作(请参阅js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
并在js中
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
可能不是最好的解决方案,当然可以改进,但这是另一种选择如果要在父窗口中保留“样式”标签
#21 楼
在这里,域内有两件事iFrame部分
页面已加载到iFrame内
,因此您要按照以下方式设置这两部分的样式,
1。 iFrame部分的样式
它可以使用具有相应
id
或class
名称的CSS进行样式设置。您也可以在父样式表中为其设置样式。<style>
#my_iFrame{
height: 300px;
width: 100%;
position:absolute;
top:0;
left:0;
border: 1px black solid;
}
</style>
<iframe name='iframe1' id="my_iFrame" src="#" cellspacing="0"></iframe>
2。设置加载到iFrame中的页面的样式
可以使用Javascript从父页面加载此样式
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
,然后设置CSS文件到受关注的iFrame部分
//to Load in the Body Part
frames['my_iFrame'].document.body.appendChild(cssFile);
//to Load in the Head Part
frames['my_iFrame'].document.head.appendChild(cssFile);
此处,您也可以使用这种方法在iFrame中编辑页面的页眉部分
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
#22 楼
var link1 = document.createElement('link');
link1.type = 'text/css';
link1.rel = 'stylesheet';
link1.href = "../../assets/css/normalize.css";
window.frames['richTextField'].document.body.appendChild(link1);
评论
我已经多次检查了这个答案,这里的richTextField是什么?
– Kirankumar Dafda
16年3月3日在9:12
这是iframe名称
– Jeeva
16 Dec 3'在10:35
我没有尝试过,但我想它不会,因为它与沙盒相对
– Jeeva
16年5月5日在22:15
#23 楼
我们可以将样式代码插入iframe。<style type="text/css" id="cssID">
.className
{
background-color: red;
}
</style>
<iframe id="iFrameID"></iframe>
<script type="text/javascript">
$(function () {
$("#iFrameID").contents().find("head")[0].appendChild(cssID);
//Or $("#iFrameID").contents().find("head")[0].appendChild($('#cssID')[0]);
});
</script>
评论
这行不通。似乎正确插入了样式标签,但其中没有内容,也没有ID。
– darylknight
2014年9月26日12:11
#24 楼
有一个很棒的脚本,可以用自身的iframe版本替换节点。CodePen演示
用法示例:
// Single node
var component = document.querySelector('.component');
var iframe = iframify(component);
// Collection of nodes
var components = document.querySelectorAll('.component');
var iframes = Array.prototype.map.call(components, function (component) {
return iframify(component, {});
});
// With options
var component = document.querySelector('.component');
var iframe = iframify(component, {
headExtra: '<style>.component { color: red; }</style>',
metaViewport: '<meta name="viewport" content="width=device-width">'
});
评论
你为什么想这么做?!
–迪伦·沃森(Dylan Watson)
18年7月7日在23:59
#25 楼
作为替代方案,您可以使用CSS-in-JS技术,如下面的lib:https://github.com/cssobj/cssobj
它可以注入JS对象作为CSS到iframe,动态地
#26 楼
这只是一个概念,但是没有安全检查和过滤就不要实现它!否则脚本可能会入侵您的网站!答案:如果您控制目标站点,则可以设置接收方脚本,例如:
1)使用
style
参数设置iframe链接,例如:http://your_site.com/target.php?color=red
(最后一句话是由
a{color:red}
函数编码的urlencode
。2)将接收方页面设置为
target.php
,如下所示:<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
评论
警告:这是最好的注射。
–卡诺
18年8月21日在12:16
是的,不要这样做,除非您要在服务器上加载大量的笔测试机器人和脚本小子=)...
–外
19年7月22日在13:45
我现在更新了答案,并添加了安全警告
–T.Todua
19年8月16日在17:12
#27 楼
好吧,我遵循了以下步骤:用一个类来保存
iframe
将
iframe
添加到div
中。在CSS文件中,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
在IE 6中有效。应该在其他浏览器中工作,请检查! />
评论
需要在iframe中控制div,这不需要
– MSD
2011年3月7日在18:12
评论
这是可能的,但前提是iframe的域与父域相同gawpertron,只是为了澄清一下,您是说如果我使用我无法控制的其他领域的iFrame内容,那么我无法控制该内容的CSS吗?
您能否列出该页面的链接,以便我们仅能够查看我们的更改。
域,端口和协议必须相同,也不能与子域一起使用。