CSSをiframeに適用する方法は?


1017

(RSSリンクを表示するための)iframeセクションがいくつかあるシンプルなページがあります。メインページからiframeに表示されているページに同じCSS形式を適用するにはどうすればよいですか?


66
それは可能ですが、iframeのドメインが親と同じである場合に限られます
gawpertron 2010年

13
明確にするために、私が制御していない他のドメインのiFrameコンテンツを使用している場合、そのコンテンツのCSSを制御する方法がないと言っていますか?
Ville M

変更を確認できるように、ページへのリンクを記載してください。

5
ドメイン、ポート、プロトコルは同じである必要があり、サブドメインでも機能しません。
lee penkman 2014

回答:


434

編集:適切なCORSヘッダーが設定されていない場合、これはクロスドメインでは機能しません。

ここには2つの異なるものがあります。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);

30
以前に投稿されたいくつかの例は、現在html5では無効になっているようです。次のようにフレームのコンテンツにアクセスできますdocument.getElementById("myframe").contentDocument。CSSを埋め込むことはまだ私にはうまくいかないようです。
Rehno Lindeque

35
リンクはHEADにのみ表示されます
Knu

18
...document.head.appendChild(cssLink)FirefoxとSafari を使用していたときにのみ機能しました。
mojuba

24
これは実際にクロスドメインで機能しますか?そうは思いません。
Simon East

89
そのため、no1はそれをテストするためにテストする必要があります。正しい、クロスドメインでは機能しません。frames ['name']を実行するとすぐに、「安全でないJavaScriptは、URL blahを含むフレームからURL blahを含むフレームにアクセスしようとします。ドメイン、プロトコル、およびポートは一致する必要があります。」
ケビン

205

この問題は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終了タグの直前に配置されます。)

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>

幸運を!


71
必要に応じて、そのハッキングを定義で呼ぶことができます。しかし、これより優れたソリューションはありませんでした...このソリューションは、Googleサービスを妨害したり、弱点を利用するように人々をだます方法ではありません。
SequenceDigitale.com

5
このソリューションをグーグルドキュメントで機能させる方法を私は殺します。あらゆる種類のJavaScriptエラーをスローします。"
キャッチされて

1
ネヴァーマインド、私は、それを考え出し、ここで解決策を掲載:stackoverflow.com/questions/25395279/...
deweydbを

9
@ChrisHoughton FYI、それは基本的にそうではありません。ただし、iframe全体が無意味になる可能性があります(たとえば、iframeを使用する理由の1つは、カード決済などのセキュリティ上の目的のためです。ここで提案されていることを行うと、おそらく問題が発生します)。
alastair 2015

10
これを行うことにより、常にログインしていないユーザーとしてカレンダーを取得します。通常のhtml iframeでは、Googleにログインしている場合、ユーザーは自分の個人用カレンダーを表示しますが、PHPコードはユーザーのGoogleセッションIDを認識できないため、個人用カレンダーを取得できません。
bdsl 2017年

72

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

使用するブラウザによっては、これは同じドメインから提供されるページでのみ機能する場合があることに注意してください。


82
ページが別のドメインにある場合、同じ生成元ポリシーがこの機能を停止することに注意してください。
ConroyP 2008年

2
同じ考え方で、より簡潔に:<iframe onload="this.contentDocument.body.style.overflow='hidden';" />
プロテクター1

FirefoxもCORSを使用しています

59
var $head = $("#eFormIFrame").contents().find("head");

$head.append($("<link/>", {
    rel: "stylesheet",
    href: url,
    type: "text/css"
}));

@deweydbクロスドメインiframeで使用しました。しかし私はあなたの許しを請うことができるだけです!
Rami Sarieddine 2014

@ramieと複数のブラウザーでテストしましたか?ほとんどのブラウザがセキュリティエラーをスローしています。
deweydb 14

私は以前にこのアイデアを見ましたが、リンクを追加して、本当に素晴らしいプロフェッショナルなものを提出します... + up
J.Tural

29

iframeは、ほとんどのブラウザーで別のHTMLページのように普遍的に処理されます。同じスタイルシートをiframeのコンテンツに適用する場合は、そこで使用されているページから参照してください。


22
@ハングリーしかし...どうやって?
神の子

29

これは<link>、追加のスタイルシートをロードするのに使用せずに、CSSコードを直接適用する方法です。

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

これにより、iframeページのバナーが非表示になります。ご提案ありがとうございます!


1
これには、IDのiframeが必要iframeですか?
ジェレミー

1
ただ、交換する@jmalais #iframe#<id>、あるいはiframeすべてを選択するiframeのを
ゼブマッコークル

3
これは私にはうまくいかないようです。編集しようとしているiframeも、domのすぐ下にヘッドがありません。それは、htmlドキュメント内のヘッドにアクセスする必要があるということですか、それともjqueryのfind関数だけで実行できるものでしょうか?
デビッドA.フランス語

1
コンソールを確認したところ、ドメインの不一致が原因でiframeコンテンツへのアクセスがブロックされているようです。現在、Chromeを使用して、開発環境をローカルでホストしています。
デビッドA.フランス語


26

ハングリーが言ったように、iframeでページを制御している場合、最も簡単な方法は、共通のスタイルで共有CSSファイルを作成し、htmlページからリンクすることです。

そうしないと、iframeの外部ページからページのスタイルを動的に変更できる可能性が低くなります。これは、なりすましやその他のハッキングが悪用される可能性があるため、ブラウザがクロスフレームdomスクリプトのセキュリティを強化しているためです。

このチュートリアルでは、iframeのスクリプト作成に関する一般的な情報を提供します。 クロスフレームスクリプトについては、IEの観点からセキュリティの制限について説明しています。


19

上記は少し変更して動作します:

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で正常に動作します


7
myDataとは何か、どこから来るのか
Tigran

1
@Tigranはそれのためですdynamic data
Akash

13

メインページのCSSとJavaScriptを再利用する場合<IFRAME>は、Ajaxで読み込まれたコンテンツに置き換えることを検討してください。検索ボットがJavaScriptを実行できるようになったとき、これはよりSEOフレンドリーになります。

これは、ドキュメントに別のhtmlページを含むjQueryの例です。これは、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だけを提供するためにそれらを信頼する必要があることを意味します;)


1
ページのコンテンツが動的である場合、このソリューションは機能しないことに注意してください。
nickdnk 2016

12

以下は私のために働いた。

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

1
エラー:Uncaught TypeError: Cannot read property 'open' of undefined
KingRider 2016

10

上記の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();
});

1
'$ this'が機能するには、 '$(this)'である必要があります。:)
h.coates 2014

9

私のコンパクトバージョン

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

8

ここでの他の回答は、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);

7

「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="https://stackoverflow.com/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');

doc.close();

7

使用はこれを試すことができます:

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

3
iframeの出所が異なる場合、CORSメカニズムではこの回避策は許可されません。
アンダーソン氏

すべての場所でiframe-urlがCORSに対応している場合はどうなりますか?
adrhc 2018年

6

この方法でiframeのコンテンツのスタイルを設定することはできません。私の提案は、サーバーサイドスクリプト(PHP、ASP、またはPerlスクリプト)を使用するか、フィードをJavaScriptコードに変換するオンラインサービスを見つけることです。それを行う他の唯一の方法は、サーバーサイドインクルードを実行できる場合です。


29
何かができないと言うときは注意してください。実際には難しいのですが
Lathan

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

});

4

同じドメインについて多くの回答が書かれているので、クロスドメインでこれを行う方法を説明します。

まず、Post Message APIについて知っておく必要があります。2つのウィンドウ間の通信にはメッセンジャーが必要です。

これが私が作成したメッセンジャーです。

/**
 * 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);
    }

}

これを2つのウィンドウで使用して通信すると、問題を解決できます。

メインウィンドウでは、

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のチュートリアルをご覧ください。


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>

それは最善の解決策ではないかもしれませんし、確かに改善することはできますが、親ウィンドウに「スタイル」タグを保持したい場合は別のオプションです


3

ここでは、ドメイン内に2つあります

  1. iFrameセクション
  2. iFrame内に読み込まれたページ

したがって、これらの2つのセクションを次のようにスタイル設定します。

1. iFrameセクションのスタイル

これは、その尊敬とCSSを使用してスタイルすることができますidまたはclass名前。親のスタイルシートでもスタイルを設定できます。

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

2

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>

1
これは機能しません。スタイルタグを正しく挿入しているようですが、中にはコンテンツがなく、IDもありません。
darylknight 2014

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


1
私はこの答えを何度もチェックしましたが、richTextFieldここには何がありますか?
Kirankumar Dafda 2016

1
それはiframe名です
Jeeva

私は試しませんでしたが、サンドボックスに対するものではなかったのではないでしょう
Jeeva

1

最も簡単な方法は、iframeと同じ場所に別のdivを追加することです。

そのが作るz-indexあなた自身のdivイースリースタイルだけことができますので、iframeのコンテナよりも大きいです。クリックする必要がある場合pointer-events:noneは、独自のdivで使用してください。クリックする必要がある場合に備えて、iframeが機能します;)

私はそれが誰かを助けることを願っています;)


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">'
});

1
なんでそんなことしたいの?
ディランワトソン


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

3
警告:これは最高のインジェクションです。
カノ2018

1
ええ、サーバーに大量のペンテストボットとスクリプトキディが必要な場合を除いて、これを行わないでください=)...
除く

1
セキュリティ警告を追加して、回答を更新しました
T.Todua

-18

さて、私はこれらのステップに従いました:

  1. 開催するクラスのDiv iframe
  2. に追加iframeしますdiv
  3. CSSファイルでは、
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }

これはIE 6で動作します。他のブラウザでも動作するはずです。確認してください!


9
iframe内でdivを制御する必要がありますが、そうする必要はありません
MSD
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.