如何检查iframe是否已加载或是否有内容?

时间:2012-02-12 14:48:58

标签: javascript jquery iframe

我有一个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(){})

13 个答案:

答案 0 :(得分:66)

试试这个。

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

答案 1 :(得分:36)

善意使用:

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

随着标准的变化,我的答案更新了。

答案 2 :(得分:13)

最简单的选择:

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

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

答案 3 :(得分:9)

我有同样的问题并添加到此,我需要检查iframe是否加载而不管跨域策略。我正在开发一个chrome扩展,它在网页上注入某些脚本,并在iframe的父页面中显示一些内容。我尝试了以下方法,这对我来说非常合适 P.S。:在我的情况下,我确实可以控制iframe中的内容,但不能控制父网站上的内容。 (iframe托管在我自己的服务器上)

第一:
在其中创建一个data-属性的iframe(在我的情况下,这部分是在注入的脚本中)
<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');
        }
    }           
}



它可能不能完全回答这个问题,但这确实是我通过这种方法解决的这个问题的可能情况。

答案 4 :(得分:6)

我不确定你是否可以检测它是否已加载,但是你可以在加载完毕后发射一个事件:

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

编辑:正如Jesse Hallett所指出的那样,iframe加载后总是会触发,即使它已经加载了。基本上,如果iframe已经加载,则回调将立即执行。

答案 5 :(得分:5)

您可以使用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);
};
  

如果iframe contentDocument指向运行代码的其他域,则检查src将无效。

答案 6 :(得分:3)

在我的情况下,它是一个跨源框架,有时没有加载。 对我有用的解决方案是: 如果它已成功加载,那么如果您尝试此代码:

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

它不允许您访问contentDocument并抛出跨源错误 但是,如果未成功加载帧,则contentDocument将返回#document对象

答案 7 :(得分:2)

当iFrame加载时,它最初包含#document,因此检查加载状态可能最好通过检查现在的内容来工作..

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

答案 8 :(得分:1)

一个非常好的方法是使用jQuery AJAX。父框架如下所示:

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

iframe_load.php文件将加载jQuery库和一个试图在AJAX GET中加载目标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: *" ) ;

答案 9 :(得分: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);

});

免责声明:仅适用于SAME ORIGIN IFRAME文档。

答案 10 :(得分:0)

如果您需要知道何时可以准备操作iframe,请使用一个间隔。在这种情况下,我每250毫秒“ ping”一次内容,如果目标iframe内有任何内容,请停止“ ping”并执行某些操作。

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

答案 11 :(得分:0)

如果您在相同域上托管网页和iframe,则可以收听iframe的Window.DOMContentLoaded事件。您必须先等待原始页面触发DOMContentLoaded,然后在iframe的DOMContentLoaded上附加一个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!');
    });
});

答案 12 :(得分:0)

你可以这样做:

const $iframe = document.querySelector(`iframe`);

$iframe.addEventListener("load", function () {
    console.log("loaded");
});
相关问题