1131

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

4

28 回答 28

479

编辑:除非设置了适当的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);
于 2008-10-20T09:07:48.327 回答
218

我用Google Calendar遇到了这个问题。我想在较暗的背景上设置样式并更改字体。

幸运的是,嵌入代码中的 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>

祝你好运!

于 2012-09-20T22:21:17.443 回答
82

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

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

于 2008-10-20T08:58:47.487 回答
63
var $head = $("#eFormIFrame").contents().find("head");

$head.append($("<link/>", {
    rel: "stylesheet",
    href: url,
    type: "text/css"
}));
于 2012-11-21T16:17:35.670 回答
36

这是直接应用 CSS 代码而不使用<link>加载额外样式表的方法。

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

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

于 2013-10-15T22:47:12.780 回答
27

大多数浏览器都像处理不同的 HTML 页面一样普遍处理 iframe。如果您想将相同的样式表应用于 iframe 的内容,只需从其中使用的页面中引用它。

于 2008-10-20T08:37:01.697 回答
27

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

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

本教程可能会为您提供有关编写 iframe 脚本的更多信息。 关于跨框架脚本从 IE 的角度解释了安全限制。

于 2008-10-20T08:52:14.440 回答
20

上面有一点改变的作品:

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

于 2009-07-28T22:53:01.340 回答
15

以下对我有用。

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();
于 2011-05-23T16:22:09.950 回答
13

如果您想从主页重用 CSS 和 JavaScript,也许您应该考虑替换<IFRAME>为 Ajax 加载的内容。当搜索机器人能够执行 JavaScript 时,这对 SEO 更加友好。

这是一个jQuery示例,它将另一个 html 页面包含到您的文档中。这比 SEO 友好得多iframe。为了确保机器人没有索引包含的页面,只需添加它以禁止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 ;)

于 2010-03-02T07:16:41.303 回答
13

扩展上述 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();
});
于 2013-06-24T11:14:10.567 回答
12

使用可以试试这个:

$('iframe').load( function() {
     $('iframe').contents().find("head")
     .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
  });
于 2017-09-01T10:15:49.467 回答
11

我的紧凑版

<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>
于 2013-03-21T09:07:13.617 回答
10

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

首先,您需要了解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 和 iframe教程。

于 2019-11-06T03:53:13.997 回答
8

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

此代码使用 vanilla 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);
于 2016-07-07T00:59:53.687 回答
7

When you say "doc.open()" it means you can write whatever HTML tag inside the iframe, so you should write all the basic tags for the HTML page and if you want to have a CSS link in your iframe head just write an iframe with CSS link in it. I give you an example:

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();
于 2010-11-08T06:25:23.147 回答
6

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

于 2009-03-31T21:36:42.360 回答
4

如果您可以访问 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>');

});
于 2016-05-19T20:20:18.843 回答
3

我找到了另一种将样式放在主 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>

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

于 2015-03-18T14:51:00.680 回答
3

我们可以在 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>
于 2014-09-02T15:18:10.807 回答
3

我认为最简单的方法是在与 iframe 相同的位置添加另一个 div,然后

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

我希望它会帮助某人;)

于 2014-07-31T12:34:27.240 回答
3

这里,域里面有两个东西

  1. iFrame 部分
  2. 在 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" }
     ));
于 2016-12-29T03:47:08.010 回答
2

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

于 2016-10-28T03:14:28.803 回答
1

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

https://github.com/cssobj/cssobj

它可以动态地将 JS 对象作为 CSS 注入 iframe

于 2017-01-04T02:27:00.817 回答
1

有一个很棒的脚本可以用自己的 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">'
});
于 2016-10-03T19:41:01.883 回答
0

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

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

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

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>
..........
于 2016-10-17T08:01:32.613 回答
0

这就是我在生产中的做法。需要注意的是,如果 iframe 属于其他网站,则会触发 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事件附加到 iframe:

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);
});
于 2021-11-17T01:47:38.273 回答
-20

好吧,我已按照以下步骤操作:

  1. Div 与要举行的班级iframe
  2. 添加iframediv.
  3. 在 CSS 文件中,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }

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

于 2010-12-08T09:46:02.987 回答