web-dev-qa-db-ja.com

ネストされたiframe、別名iframe Inception

JQueryを使用して、div id = "element"にアクセスしようとしています。

<body>
    <iframe id="uploads">
        <iframe>
            <div id="element">...</div>
        </iframe>
    </iframe>
</body>

すべてのiframeは同じドメイン上にあり、www/www以外の問題はありません。

最初のiframe内の要素は正常に選択されましたが、2番目のネストされたiframeは選択されていません。

私はいくつかのことを試しましたが、これは最新のものです(そしてかなり必死の試みです)。

var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');

// iframeContent is null

編集:タイミングの問題を除外するために、クリックイベントを使用してしばらく待ちました。

jQuery().click(function(){
   var iframe = jQuery('#upload').contents().find('iframe');
   console.log(iframe.find('#element')); // [] null
});

何か案は?ありがとう。

更新:次のように2番目のiframeを選択できます...

var iframe = jQuery('#upload').contents().find('iframe');

問題は、iframeがjavascriptで生成されるため、srcが空であるということです。したがって、iframeは選択されていますが、コンテンツの長さは0です。

42
Ian Brindley

つまり、<iframe>要素には次のような「src」プロパティが必要なので、指定したコードは機能しません。

<iframe id="uploads" src="http://domain/page.html"></iframe>

.contents()を使用してコンテンツを取得してもかまいません。

$('#uploads).contents()は2番目のiframeへのアクセスを提供しますが、そのiframeが「内部」にある場合は、http://domain/page.html文書に#uploads iframeがロードされます。

私がこれについて正しいことをテストするために、main.html、iframe.html、noframe.htmlという名前の3つのhtmlファイルを作成し、div#elementを選択しました。

$('#uploads').contents().find('iframe').contents().find('#element');

Iframeがリソースをロードするのを待つ必要があるため、要素が利用できなくなる遅延があります。また、すべてのiframeは同じドメインに存在する必要があります。

お役に立てれば ...

使用した3つのファイルのhtmlを次に示します(「src」属性をドメインとURLに置き換えます)。

main.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>main.html example</title>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script>
        $(function () {
            console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first

            setTimeout( function () {
                console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
            }, 2000 );

        });
    </script>
</head>
<body>
    <iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>

iframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>iframe.html example</title>
</head>
<body>
    <iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>

noframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>noframe.html example</title>
</head>
<body>
    <div id="element">some content</div>
</body>
59
Carlos Castillo

var iframeInner = jQuery(iframe).find('iframe').contents();

var iframeContent = jQuery(iframeInner).contents().find('#element');

iframeInnerの要素が含まれています

<div id="element">other markup goes here</div> 

iframeContentは、内部にある要素を検索します

 <div id="element">other markup goes here</div> 

(findは現在の要素を検索しません)それがnullを返す理由です。

13
Bhargavi Gunda

ちょっと私はあなたがしたいことをしているように見える何かを得た。いくつかの汚いコピーが含まれますが、動作します。作業コードを見つけることができます こちら

これがメインのhtmlファイルです。

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function(){
            Iframe = $('#frame1');

            Iframe.on('load', function(){
                IframeInner = Iframe.contents().find('iframe');

                IframeInnerClone = IframeInner.clone();

                IframeInnerClone.insertAfter($('#insertIframeAfter')).css({display:'none'});

                IframeInnerClone.on('load', function(){
                    IframeContents = IframeInner.contents();

                    YourNestedEl = IframeContents.find('div');

                    $('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
                });
            });
        });
    </script>
</head>
<body>
    <div id="insertIframeAfter">Hello!!!!</div>
    <iframe id="frame1" src="Test_Iframe.html">

    </iframe>
</body>
</html>

ご覧のとおり、最初のIframeが読み込まれたら、2番目のIframeを取得して複製します。次に、domに再挿入して、onloadイベントにアクセスできるようにします。これが読み込まれたら、クローンされていないものからコンテンツを取得します(同じsrcを使用するため、同様に読み込まれている必要があります)。その後、あなたはコンテンツであなたがしたいことをすることができます。

Test_Iframe.htmlファイルは次のとおりです。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>Test_Iframe</div>
    <iframe src="Test_Iframe2.html">
    </iframe>
</body>
</html>

およびTest_Iframe2.htmlファイル:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>I am the second nested iframe</div>
</body>
</html>

カラーボックス、非表示フィールド、iframeなど、後でレンダリングされる要素にはliveメソッドを使用する必要があります

$(".inverter-value").live("change",function() {
     elem = this
    $.ajax({
      url: '/main/invertor_attribute/',
      type: 'POST',
      aysnc: false,
      data: {id: $(this).val() },
      success: function(data){
       // code
      },
      dataType: 'html'
    });
  });
1
Tauqeer Ahmad

おそらくタイミングの問題があります。 document.readyコマンドは、おそらく2番目のiFrameがロードされる前に起動されます。さらに役立つ情報はありませんが、問題の可能性があると思われる場合はお知らせください。

1
Carntel

あなたの問題は、jQueryがiframeにロードされていないことだと思います。

最も安全なアプローチは、純粋なDOMベースの方法に依存してコンテンツを解析することです。

または、jQueryで開始し、iframe内で1回、typeof window.jQuery == 'undefined'であるかどうかを1回テストし、trueの場合、jQueryはその内部で有効にならず、DOMベースのメソッドでフォールバックします。

0
Mathieu Amiot

あなたのdivに到達するための最良の方法だと思います:

var your_element=$('iframe#uploads').children('iframe').children('div#element');

それはうまくいくはずです。

0
csaron92

ブラウザがiframeをサポートしている場合、iframe内のDOMはそれぞれのタグのsrc属性から取得されます。 iframeタグ内のコンテンツは、ブラウザがiframeタグをサポートしないフォールバックメカニズムとして使用されます。

参照: http://www.w3schools.com/tags/tag_iframe.asp

0
Gladwin Burboz