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

new*_*e29 69 javascript iframe jquery

我有一个id ="myIframe"的iframe,这里我的代码加载它的内容:

$('#myIframe').attr("src", "my_url");
Run Code Online (Sandbox Code Playgroud)

问题是有时加载时间太长,有时加载速度很快.所以我必须使用"setTimeout"函数:

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

我想知道的是如何确定iFrame是否已加载或是否具有内容.使用iframe.contents().find()不起作用.我不能用iframe.load(function(){}).

Bir*_*chi 73

试试这个.

<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();"> 
Run Code Online (Sandbox Code Playgroud)

  • 将字符串传递给setTimeout()的缺点.传递函数引用更简洁:`setTimeout(checkIframeLoaded,100);` (19认同)
  • 如果iframe来自另一个域,这将不起作用:`VM29320:1未捕获DOMException:阻止具有原始"http:// localhost:9002"的帧访问跨源帧. (14认同)
  • 这会导致“不安全的 JavaScript 尝试从具有 url2 的框架中访问具有 URL url1 的框架,域、协议和端口必须匹配。” (3认同)
  • 我不得不说这是唯一对我有用的解决方案.您无法信任iframe上的load事件,因为它在IE11,Chrome和Edge上的大多数情况下会立即触发,并且`iframe.contentDocument.location.href`显示为"about:blank".即使在HTML中直接指定`iframe`的`src`,这似乎也是正确的. (3认同)

pra*_*abu 42

善意使用:

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

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

  • 调用jQuery现已弃用^^ (30认同)
  • 现在不推荐调用.load.请改用.on('load',function(){}) (5认同)
  • 这种方法根本不起作用,因为事件会立即触发,因为`iframe通常以`src ="about:blank"`开头,即使`src`直接在HTML中指定或在`iframe`节点之前指定被添加到DOM中.我通过在IE11,Chrome和Edge的紧密循环中轮询`iframe`的`contentDocument.location.href`来测试这个.如果被框架的内容通过元标记或javascript重定向,它也不起作用. (2认同)

Ora*_*ane 14

最简单的选择:

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

<iframe onload="frameload()" src=...>
Run Code Online (Sandbox Code Playgroud)

  • 不是一个可靠的解决方案,因为即使网址被破坏也会发出警报. (9认同)

Tus*_*kla 10

我有同样的问题并添加到此,我需要检查是否加载iframe而不管跨域策略.我正在开发一个chrome扩展,它在网页上注入某些脚本,并在iframe的父页面中显示一些内容.我尝试了以下方法,这对我来说非常适合.
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);
Run Code Online (Sandbox Code Playgroud)



现在回到我的案例中注入的脚本:

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);
Run Code Online (Sandbox Code Playgroud)


和,

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');
        }
    }           
}
Run Code Online (Sandbox Code Playgroud)



它可能不完全回答问题,但它确实是这个问题的一个可能的例子,我通过这种方法解决了.


ski*_*rk1 6

我不确定你是否可以检测它是否已加载,但是你可以在加载后触发事件:

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

编辑:正如杰西哈利特所指出的那样iframe,即使它已经加载,也会在加载时触发.基本上,如果iframe已加载,则回调将立即执行.

  • 关于这个方法的好处是,即使你在iframe完全加载后绑定它,jQuery'ready'事件也会触发.因此,检查iframe是否已包含内容或在获取内容时通知您是一种好方法. (2认同)

Max*_*ber 6

您可以使用iframe的load事件在iframe加载时进行响应。

document.querySelector('iframe').onload = function(){
    console.log('iframe loaded');
};
Run Code Online (Sandbox Code Playgroud)

这不会告诉您是否加载了正确的内容:要进行检查,可以检查contentDocument

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

contentDocument如果iframe src指向与代码运行所在的域不同的域,则无法进行检查。

  • 请考虑编辑您的帖子,以添加更多有关代码功能以及为什么它可以解决问题的解释。通常仅包含代码(即使它在起作用)的答案通常不会帮助OP理解他们的问题。 (2认同)

Raz*_*med 6

就我而言,它是一个跨域框架,有时无法加载。对我有用的解决方案是:如果它成功加载,那么如果您尝试以下代码:

var iframe = document.getElementsByTagName('iframe')[0];
console.log(iframe.contentDocument);
Run Code Online (Sandbox Code Playgroud)

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