iframeが読み込まれているか、コンテンツが含まれているかを確認するにはどうすればよいですか?


83

id = "myIframe"のiframeがあり、そのコンテンツをロードするコードがあります。

$('#myIframe').attr("src", "my_url");

問題は、ロードに時間がかかりすぎることもあれば、非常に速くロードされることもあります。したがって、「setTimeout」関数を使用する必要があります。

setTimeout(function(){
   if (//something shows iframe is loaded or has content)
   {
       //my code
   }
   else
   {
       $('#myIframe').attr("src",""); //stop loading content
   }
},5000);

私が知りたいのは、iFrameがロードされているかコンテンツが含まれているかを確認する方法だけです。使用iframe.contents().find()は機能しません。使えませんiframe.load(function(){})


それで、ロードに5秒以上かかる場合、iframeに何もロードさせたくないですか?
skimberk1 2012

ご協力いただきありがとうございます :) 。はい、ロードに5秒以上かかる場合は、iframeに何もロードしたくありません。以下に示すように「.ready()」を使用しても機能しません。
newbie29 2012

ここで私の答えを参照してくださいstackoverflow.com/questions/17158932/…–

回答:


88

これを試して。

<script>
function checkIframeLoaded() {
    // Get a handle to the iframe element
    var iframe = document.getElementById('i_frame');
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

    // Check if loading is complete
    if (  iframeDoc.readyState  == 'complete' ) {
        //iframe.contentWindow.alert("Hello");
        iframe.contentWindow.onload = function(){
            alert("I am loaded");
        };
        // The loading is complete, call the function we want executed once the iframe is loaded
        afterLoading();
        return;
    } 

    // If we are here, it is not loaded. Set things up so we check   the status again in 100 milliseconds
    window.setTimeout(checkIframeLoaded, 100);
}

function afterLoading(){
    alert("I am here");
}
</script>

<body onload="checkIframeLoaded();"> 

21
文字列をsetTimeout()に渡すことのデメリット。関数参照を渡す方がクリーンです:setTimeout(checkIframeLoaded, 100);
Jesse Hallett 2013

1
これは、「安全でないJavaScriptが、URL2のフレームからURL url1のフレームにアクセスしようとする試みです。ドメイン、プロトコル、およびポートは一致する必要があります。」
mohamed-ibrahim 2013

これは私が達成しようとしていたことに対する最良の解決策でした。iFrame内でAngularJSを使用しており、含まれているファイルの読み込みを遅らせるng-includeを使用しています。onloadイベントでIframeのコンテンツを印刷しようとしましたが、起動が早すぎました。readyState === "complete"すべてがロードされるまで変更されないため、チェックすることでうまくいきました。
Jeffrey A. Gochin 2016

3
これが私にとってもうまくいった唯一の解決策だったと言わざるを得ません。それはIE11、クロム、およびエッジ上のほとんどの場合、すぐに起動するようあなただけで、IFRAMEの上にloadイベントを信頼することはできませんiframe.contentDocument.location.hrefとして示しますabout:blank。これは、srcforiframeがHTMLで直接指定されている場合でも当てはまるようです。
rmalayter 2016年

21
:IFRAMEが別のドメインから来ている場合、これは動作しませんVM29320:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:9002" from accessing a cross-origin frame.
オーギュRiedinger

45

親切に使用してください:

$('#myIframe').on('load', function(){
    //your code (will be called once iframe is done loading)
});

基準が変更されたので私の答えを更新しました。


5
.loadの呼び出しは非推奨になりました。代わりに.on( 'load'、function(){})を使用してください
Graham T

51
jQueryの呼び出しは非推奨になりました^^
cchamberlain 2016

4
HTMLで直接指定されている場合や、ノードがDOMに追加される前であっても、iframesは通常、で始まるため、このアプローチはまったく機能しません。IE11、Chrome、およびEdgeのタイトループでのをポーリングして、これをテストしました。フレーム化されているコンテンツがメタタグまたはjavascriptを介してリダイレクトする場合も機能しません。src="about:blank"srciframeiframecontentDocument.location.href
rmalayter 2016年

17

同じ問題があり、これに追加しました。クロスドメインポリシーに関係なく、iframeが読み込まれるかどうかを確認する必要がありました。Webページに特定のスクリプトを挿入し、親ページのコンテンツをiframeに表示するChrome拡張機能を開発していました。私は次のアプローチを試しましたが、これは私にとって完璧に機能しました。
PS:私の場合、iframeのコンテンツは制御できますが、親サイトは制御できません。(Iframeは自分のサーバーでホストされています)

最初に:次のような属性を
持つiframeを作成しますdata-(私の場合、この部分は挿入されたスクリプトにありました)
<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>

次に、iframeコードで次を使用します

var sourceURL = document.referrer;
window.parent.postMessage('1',sourceURL);



私の場合のように、挿入されたスクリプトに戻ります。

setTimeout(function(){
  var myIframe = document.getElementById('myiframe');
  var isLoaded = myIframe.prop('data-isloaded');
  if(isLoaded != '1')
  {
    console.log('iframe failed to load');
  } else {
    console.log('iframe loaded');
  }
},3000);


そして、

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
    if(event.origin !== 'https://someWebsite.com') //check origin of message for security reasons
    {
        console.log('URL issues');
        return;
    }
    else {
        var myMsg = event.data;
        if(myMsg == '1'){
            //8-12-18 changed from 'data-isload' to 'data-isloaded
            $("#myiframe").prop('data-isloaded', '1');
        }
    }           
}



それは質問に正確に答えないかもしれませんが、それは確かに私がこの方法で解決したこの質問の可能なケースです。


document.getElement-> s <-ByIdのように、コードにいくつかのエラーがありますが、アイデア全体が役立ちます。できます。ありがとう)
JohnK 2017年

@JohnKそれを指摘してくれてありがとう、私はそれを修正しました。これがあなたに役立つことを知ってうれしいです。
Tushar Shukla 2017

12

最も簡単なオプション:

<script type="text/javascript">
  function frameload(){
   alert("iframe loaded")
  }
</script>

<iframe onload="frameload()" src=...>

10
URLが壊れていてもアラートが表示されるため、固溶体ではありません。
bboy 2014

7

iframeのloadイベントを使用して、iframeが読み込まれたときに応答できます。

document.querySelector('iframe').onload = function(){
    console.log('iframe loaded');
};

これでは、正しいコンテンツが読み込まれたかどうかはわかりません。それを確認するには、を調べますcontentDocument

document.querySelector('iframe').onload = function(){
    var iframeBody = this.contentDocument.body;
    console.log('iframe loaded, body is: ', body);
};

contentDocumentiframeがsrcコードの実行場所とは異なるドメインを指している場合、チェックは機能しません。


2
投稿を編集して、コードの機能と問題が解決する理由についての説明を追加することを検討してください。ほとんどの場合、コードが含まれているだけの回答(機能している場合でも)は、通常、OPが問題を理解するのに役立ちません。
SuperBiasedMan 2015年

5

ロードされているかどうかを検出できるかどうかはわかりませんが、ロードが完了したらイベントを発生させることができます。

$(function(){
    $('#myIframe').ready(function(){
        //your code (will be called once iframe is done loading)
    });
});

編集: Jesse Hallettが指摘したように、これは、iframeロードされている場合でも、ロードされている場合は常に起動します。したがって、基本的に、iframeがすでにロードされている場合、コールバックはすぐに実行されます。


2
このメソッドの良いところは、iframeが完全にロードされた後にバインドしても、jQueryの「ready」イベントが発生することです。したがって、iframeにすでにコンテンツがあるかどうかを確認したり、コンテンツを取得したときに通知したりするのに適した方法です。
ジェシーハレット2013

1
これは、iframeに対して1回だけ発生するようです。ただし、iframeにリンクが含まれていると、iframeのコンテンツが再読み込みされる可能性があるため、このイベントは再度発生しません。これはあなたのケースであれば、@pratikabuで答えを使用-$('#myIframe').load(function(){ })
ragamufin

@ skimberk1こんにちは、この回答によると、ソリューションは機能しません。jqueryはDOMがロードされているかどうかを記憶する変数を保持し、onleyはiframeのDOMではなく現在のフレームの現在のDOMをチェックするからです。
マルコメドラノ2014年

はい、イベントを開催したり、ビデオを表示したり、準備ができたら音楽を再生したりできます。非常に有益です
。– Giridhar Karnik 2015

このチケットによると、iframeで使用するdev.jquery.com/ticket/5511readyは、jQueryが実行されているフレーム以外の他のドキュメントではサポートされていないため、常にすぐに関数を実行します。
男2016年

5

私の場合、それはクロスオリジンフレームであり、時々ロードされませんでした。私のために働いた解決策は次のとおりです:それが正常にロードされた場合、このコードを試してみると:

var iframe = document.getElementsByTagName('iframe')[0];
console.log(iframe.contentDocument);

contentDocumentクロスオリジンエラーにアクセスしてスローすることはできませんが、フレームが正常にロードされない場合はオブジェクトcontentDocumentが返され#documentます


2

iFrameが読み込まれると、最初は#documentが含まれているため、読み込み状態を確認するには、現在何があるかを確認するのが最適な場合があります。

if ($('iframe').contents().find('body').children().length > 0) {
    // is loaded
} else {
    // is not loaded
}

6
別のドメインにある場合、これは失敗します
Funkodebat 2015年

iframeがロード中(完全にロードされていない)である可能性があるため、これは正しくありません。
MikeShiyan19年

1

私は次のように動作するトリックを得ました:[クロスブラウザをテストしていません!]

次のように定義されたiframeのonloadイベントハンドラーを定義します

$('#myIframe').on('load', function() {
    setTimeout(function() {
        try {
            console.log($('#myIframe')[0].contentWindow.document);
        } catch (e) {
            console.log(e);
            if (e.message.indexOf('Blocked a frame with origin') > -1 || e.message.indexOf('from accessing a cross-origin frame.') > -1) {
                alert('Same origin Iframe error found!!!');
                //Do fallback handling if you want here
            }
        }
    }, 1000);

});

免責事項:同じORIGINIFRAMEドキュメントに対してのみ機能します。


0

本当に素晴らしい方法は、jQueryAJAXを使用することです。親フレームは次のようになります。

<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>

iframe_load.phpファイルは、jQueryライブラリとAJAXGETで宛先URLを読み込もうとするJavaScriptを読み込みます。

var the_url_to_load = "http://www.your-website.com" ;
$.ajax({
            type: "GET",
            url: the_url_to_load,
            data: "",
            success: function(data){
                // if can load inside iframe, load the URL
                location.href = the_url_to_load ;
            },
            statusCode: {
                500: function() {
                    alert( 'site has errors' ) ;
                }
            },
            error:function (xhr, ajaxOptions, thrownError){
                // if x-frame-options, site is down or web server is down
                alert( 'URL did not load due to x-frame-options' ) ;
            } });

重要宛先には「Access-Control-Allow-Origin」ヘッダーが含まれている必要があります。PHPの例:

HEADER( "Access-Control-Allow-Origin: *" ) ;

0

iframeを操作する準備ができたことを知る必要がある場合は、間隔を使用してください。この場合、I「ピング」は、コンテンツごとに250ミリ秒があるかどうあらゆるターゲットのiframe内のコンテンツは、「ピング」を停止して何かをします。

var checkIframeLoadedInterval = setInterval( checkIframeLoaded, 250 );

function checkIframeLoaded() {
    var iframe_content = $('iframe').contents();

    if (iframe_content.length > 0) {
        clearInterval(checkIframeLoadedInterval);

        //Apply styles to the button
        setTimeout(function () {
            //Do something inside the iframe 
            iframe_content.find("body .whatever").css("background-color", "red");
        }, 100); //100 ms of grace time
    }
}

0

同じドメインでページとiframeをホストしている場合は、iframeのWindow.DOMContentLoadedイベントをリッスンできます。DOMContentLoaded最初に元のページが起動するのを待ってからDOMContentLoaded、iframeにイベントリスナーをアタッチする必要がありWindowます。

次のようなiframeがあるとすると、

<iframe id="iframe-id" name="iframe-name" src="..."></iframe>

次のスニペットでは、iframeのDOMContentLoadedイベントにフックできます。

document.addEventListener('DOMContentLoaded', function () {
    var iframeWindow = frames['iframe-name'];
    // var iframeWindow = document.querySelector('#iframe-id').contentWindow
    // var iframeWindow = document.getElementById('iframe-id').contentWindow

    iframeWindow.addEventListener('DOMContentLoaded', function () {
        console.log('iframe DOM is loaded!');
    });
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.