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


当前回答

有一个很棒的脚本可以用节点本身的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">'
});

其他回答

iframe被大多数浏览器像处理一个不同的HTML页面一样处理。如果希望对iframe的内容应用相同的样式表,只需从其中使用的页面引用它。

可以试试这个:

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

由于许多答案都是针对相同的域编写的,我将在跨域中编写如何做到这一点。

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

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

这是一个jQuery的例子,包括另一个html页面到您的文档。这比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>

你也可以直接从谷歌:http://code.google.com/apis/ajaxlibs/documentation/中包含jQuery——这意味着可选的自动包含新版本和一些显著的速度提升。同时,这意味着你必须相信他们交付给你的只是jQuery;)

以上方法稍加改变即可奏效:

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