如何将CSS应用于iFrame?

我有一个简单的页面,其中有一些ifram部分(用于显示RSS链接)。如何将主页面的相同CSS格式应用于ifram中显示的页面?

1511863 次浏览

大多数浏览器都像处理不同的超文本标记语言页面一样处理ifram。如果您想将相同的样式表应用于ifram的内容,只需从其中使用的页面引用它。

如果您控制ifram中的页面,正如Hangy所说,最简单的方法是创建一个具有通用样式的共享CSS文件,然后只需从您的html页面链接到它。

否则,您不太可能从ifram中的外部页面动态更改页面的样式。这是因为浏览器由于可能被滥用于欺骗和其他黑客行为而加强了跨帧dom脚本的安全性。

本教程可以为您提供有关一般脚本ifram的更多信息。关于跨帧脚本从IE的角度解释了安全限制。

如果ifram的内容不完全在您的控制之下,或者您想从具有不同样式的不同页面访问内容,您可以尝试使用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);

请注意,根据您使用的浏览器,这可能仅适用于来自同一域的页面。

编辑:除非设置了适当的CORS报头,否则这不适用于跨域。

这里有两个不同的东西:ifram块的样式和嵌入ifram的页面样式。您可以按照通常的方式设置ifram块的样式:

<iframe name="iframe1" id="iframe1" src="empty.htm"frameborder="0" border="0" cellspacing="0"style="border-style: none;width: 100%; height: 120px;"></iframe>

嵌入在ifram中的页面的样式必须通过将其包含在子页面中来设置:

<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);

您将无法以这种方式设置ifram内容的样式。我的建议是使用服务器端脚本(PHP、ASP或Perl脚本)或找到将提要转换为JavaScript代码的在线服务。唯一的其他方法是如果您可以执行服务器端包含。

上面有一点变化的作品:

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 firstdoc.open();doc.write(myData);doc.close();
//Then append childdoc.body.appendChild(cssLink);

至少与ff3和ie8配合使用

如果您想从主页重用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;)

当你说“doc.open()”时,它意味着你可以在ifram中编写任何超文本标记语言标签,所以你应该为超文本标记语言页面编写所有基本标签,如果你想在ifram头中有一个CSS链接,只需编写一个带有CSS链接的ifram。我给你一个例子:

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();

我遵循了这些步骤:

  1. 具有要保存的类的Diviframe
  2. iframe添加到div
  3. 在CSS文件中,
divClass { width: 500px; height: 500px; }divClass iframe { width: 100%; height: 100%; }

这适用于IE 6。应该适用于其他浏览器,请检查!

下面的工作对我来说。

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();

我在谷歌日历中遇到了这个问题。我想在较暗的背景上设置样式并更改字体。

幸运的是,嵌入代码中的URL对直接访问没有限制,因此通过使用PHP函数file_get_contents可以获得页面中的全部内容。可以调用位于您的服务器上的php文件,而不是调用Google URL,例如。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结束标记之前。)

在css和js相对调用的情况下,从原始url中指定基本url:

$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>

祝你好运!

var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {rel: "stylesheet",href: url,type: "text/css"}));

我的紧凑版

<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 listenerfrmHead.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>

扩展上述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代码,而无需使用<link>加载额外的样式表。

var head = jQuery("#iframe").contents().find("head");var css = '<style type="text/css">' +'#banner{display:none}; ' +'</style>';jQuery(head).append(css);

这会隐藏ifram页面中的横幅。谢谢你的建议!

我认为最简单的方法是添加另一个div,在ifram的同一个地方,然后

使其z-index比ifram容器大,这样你就可以轻松地设置自己的div。如果你需要单击它,只需在你自己的div上使用pointer-events:none,这样ifram就可以工作,以防你需要单击它;)

希望对大家有帮助;)

我们可以将样式标签插入ifram。

<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>

我找到了另一种解决方案,将样式放在主html中,如下所示

<style id="iframestyle">html {color: white;background: black;}</style><style>html {color: initial;background: initial;}iframe {border: none;}</style>

然后在ifram中执行此操作(请参阅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>

它可能不是最好的解决方案,当然可以改进,但如果您想在父窗口中保留“样式”标签,这是另一种选择

如果您可以访问ifram页面并希望只有在您通过页面上的ifram加载时才能在其上应用不同的CSS,那么在这里我找到了解决此类问题的解决方案

即使ifram正在加载不同的域,这也有效

查看postMessage()

计划是,将css作为消息发送到iFrame,例如

iframenode.postMessage('h2{color:red;}','*');

*是发送此消息,而不管它在ifram中的域是什么

并在ifram中接收消息并将接收到的消息(CSS)添加到该文档头。

添加到ifram页面的代码

window.addEventListener('message',function(e){
if(e.data == 'send_user_details')document.head.appendChild('<style>'+e.data+'</style>');
});

这里的其他答案似乎使用jQuery和CSS链接。

此代码使用vanilla JavaScript。它创建了一个新的<style>元素。它将该元素的文本内容设置为包含新CSS的字符串。并将该元素直接附加到ifram文档的头部。

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);

有一个精彩的剧本将节点替换为自身的ifram版本。演示代码

在此处输入图片描述

使用示例:

// Single nodevar component = document.querySelector('.component');var iframe = iframify(component);
// Collection of nodesvar components = document.querySelectorAll('.component');var iframes = Array.prototype.map.call(components, function (component) {return iframify(component, {});});
// With optionsvar component = document.querySelector('.component');var iframe = iframify(component, {headExtra: '<style>.component { color: red; }</style>',metaViewport: '<meta name="viewport" content="width=device-width">'});

这只是一个概念,但不要在没有安全检查和过滤的情况下实现它!否则脚本可能会攻击您的网站!

答:如果您控制目标站点,您可以设置接收器脚本,如下所示:

1)使用style参数设置ifram链接,例如:

http://your_site.com/target.php?color=red

(最后一个短语是urlencode函数编码的a{color:red}

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>..........

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);

在这个领域里有两样东西

  1. iFrame部分
  2. iFrame内加载的页面

因此,您希望将这两个部分的样式设置为如下所示,

1. iFrame部分的样式

它可以使用具有受人尊敬的idclass名称的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 Partframes['my_iFrame'].document.body.appendChild(cssFile);//to Load in the Head Partframes['my_iFrame'].document.head.appendChild(cssFile);

在这里,您也可以使用这种方式在iFrame中编辑页面的头部

var $iFrameHead = $("#my_iFrame").contents().find("head");$iFrameHead.append($("<link/>",{rel: "stylesheet",href: urlPath,type: "text/css" }));

作为替代方案,您可以使用CSS-in-JS技术,如下面的lib:

https://github.com/cssobj/cssobj

它可以将JS对象作为CSS注入ifram,动态

使用可以尝试这个:

$('iframe').load( function() {$('iframe').contents().find("head").append($("<style type='text/css'>  .my-class{display:none;}  </style>"));});

由于为相同的域编写了许多答案,因此我将编写如何在跨域中执行此操作。

首先,您需要知道发布消息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 namevar 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})

然后,从Ifram接收事件。

在Ifram中:

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教程。

这就是我在生产中的做法。值得记住的是,如果ifram属于其他网站,它将触发CORS错误,将无法工作。

    var $iframe =  document.querySelector(`iframe`);var doc = $iframe.contentDocument;
var style = doc.createElement("style");style.textContent = `*{display:none!important;}`;doc.head.append(style);

在某些情况下,您可能还需要将load事件附加到ifram:

var $iframe =  document.querySelector(`iframe`);
$iframe.addEventListener("load", function() {var doc = $iframe.contentDocument;var style = doc.createElement("style");style.textContent = `*{display:none!important;}`;doc.head.append(style);});