我有一个简单的页面,其中包含一些iframe部分(用于显示RSS链接)。我如何将主页面的相同CSS格式应用于在iframe中显示的页面?
我有一个简单的页面,其中包含一些iframe部分(用于显示RSS链接)。我如何将主页面的相同CSS格式应用于在iframe中显示的页面?
在上面的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();
});
如果你想重复使用主页面的CSS和JavaScript,也许你应该考虑将<IFRAME>
替换为Ajax加载内容。当搜索机器人能够执行JavaScript时,这更有利于SEO。
这是一个jQuery示例,它将另一个HTML页面包含在文档中。这比iframe
更有助于SEO。为了确保机器人不会索引所包含的页面,只需将其添加到robots.txt
中的不允许列表中即可。
<html>
<header>
<script src="/js/jquery.js" type="text/javascript"></script>
</header>
<body>
<div id='include-from-outside'></div>
<script type='text/javascript'>
$('#include-from-outside').load('http://example.com/included.html');
</script>
</body>
</html>
你还可以直接从Google引入jQuery:http://code.google.com/apis/ajaxlibs/documentation/ - 这意味着自动引入新版本的可选项以及一些显著的速度增加。不过这也意味着你需要信任他们只提供给你jQuery ;)
我的简化版:
<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>
由于许多答案都是针对相同的域编写的,因此我将介绍如何在跨域中完成此操作。
首先,您需要了解Post Message API。我们需要一种信使来在两个窗口之间进行通信。
这是我创建的一个信使。
/**
* 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和Iframes教程以获取更多详细信息。
这里的其他答案似乎使用了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);
当你说“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();
您无法通过这种方式对iframe的内容进行样式设置。我的建议是使用服务器端脚本(PHP、ASP或Perl脚本)或查找在线服务,将源提供程序转换为JavaScript代码。另外一种方法是如果您可以进行服务器端包含。
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>');
});
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
<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>