IFRAME加载完成后的Javascript回调?

Fly*_*wat 145 javascript iframe events dom

我需要在IFRAME加载完成后执行回调.我无法控制IFRAME中的内容,因此我无法从那里触发回调.

这个IFRAME是以编程方式创建的,我需要将其数据作为回调中的变量传递,并销毁iframe.

有任何想法吗?

编辑:

这就是我现在拥有的:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}
Run Code Online (Sandbox Code Playgroud)

在iFrame加载之前进行此回调,因此回调没有返回数据.

Rem*_*arp 49

首先,通过函数名称xssRequest,听起来你正在尝试跨站点请求 - 如果这是正确的,你将无法读取iframe的内容.

另一方面,如果iframe的URL在您的域上,您可以访问正文,但我发现如果我使用超时删除iframe,则回调可以正常工作:

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});
Run Code Online (Sandbox Code Playgroud)

  • 知道如何在没有jQuery的情况下做到这一点吗? (12认同)
  • +1用于理解XSS,然后回答问题. (7认同)
  • 从jQuery 3.0开始,`load`消失了.请改用`.on('load',function(){...})`. (5认同)
  • 你可以用`this.contentDocument.body.outerHTML'替换`$('body',this.contentWindow.document).html()` (4认同)

Neo*_*Neo 35

我正在使用jQuery,令人惊讶的是,这似乎加载,因为我刚测试并加载了一个沉重的页面,我没有收到警报几秒钟,直到我看到iframe加载:

$('#the_iframe').load(function(){
    alert('loaded!');
});
Run Code Online (Sandbox Code Playgroud)

因此,如果您不想使用jQuery,请查看其源代码并查看此函数是否与iframe DOM元素的行为不同,稍后我会自己查看它,因为我感兴趣并在此处发布.此外,我只测试了最新的铬.

  • 从jQuery 3.0开始,`load`消失了.请改用`.on('load',function(){...})`. (10认同)

all*_*ode 8

iframe的innerHTML为空,因为您的iframe代码不会包含父文档中的任何内容.要从iframe的src属性引用的页面中获取内容,您需要访问iframe的contentDocument属性.如果src来自不同的域,则会抛出异常.这是一项安全功能,可以防止您在其他人的页面上执行任意JavaScript,这会产生跨站点脚本漏洞.这是一些示例代码,说明了我在说什么:

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>
Run Code Online (Sandbox Code Playgroud)

要进一步举例,请尝试将其用作iframe的内容:

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>
Run Code Online (Sandbox Code Playgroud)


Rya*_*ook 7

如果将word docs和pdf等文档流式传输到iframe并找到一个效果很好的解决方案,我必须这样做.关键是onreadystatechanged在iframe上处理事件.

让我们说你的框架的名称是"myIframe".首先在你的代码启动的某个地方(我在iframe之后的任何地方内联)添加这样的东西来注册事件处理程序:

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;
Run Code Online (Sandbox Code Playgroud)

我无法在iframe上使用onreadystatechage属性,我不记得为什么,但应用程序必须在IE 7和Safari 3中工作,所以这可能是一个因素.

以下是如何获得完整状态的示例:

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}
Run Code Online (Sandbox Code Playgroud)


Nad*_*uli 6

当i帧内容在IE上完全加载时,我想隐藏等待的微调器div,我尝试了Stackoverflow.Com中提到的每个解决方案,但没有任何工作,因为我想要的.

然后我有一个想法,当i帧内容完全加载时,可能会触发$(Window)加载事件.而这正是发生的事情.所以,我写了这个小脚本,像魔术一样工作:

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


ara*_*azi 5

如果 iFrame 已加载,此函数将立即运行您的回调函数,或者等到 iFrame 完全加载。

这还解决了以下问题:

  1. Chrome 使用一个页面初始化每个 iFrame,about:blank该页面将具有readyState == "complete". 稍后,它会将 `about:blank 替换为实际的 iframe src 值。因此,readyState的初始值不会代表实际iFrame的readyState。因此,除了检查readyState值之外,该函数还解决了about:blank问题。

  2. DOMContentLoaded事件不适用于 iFrame。因此,load如果 iFrame 尚未加载,它会使用该事件来运行回调函数。该load事件相当于readyState == "complete"用于检查 iFrame 是否已加载的事件。因此,在任何情况下,回调函数都会在 iFrame 完全加载后运行。

  3. iFrame src 可以进行重定向,因此加载与原始 src url 不同的页面。此功能也适用于该场景。

将您想要在 iFrame 完成加载时运行的回调函数和<iframe>元素传递给此函数:

function iframeReady(callback, iframeElement) {
    const iframeWindow = iframeElement.contentWindow;
    if ((iframeElement.src == "about:blank" || (iframeElement.src != "about:blank" && iframeWindow.location.href != "about:blank")) && iframeWindow.document.readyState == "complete") {
        callback();
    } else {
        iframeWindow.addEventListener("load", callback);
    }
}
Run Code Online (Sandbox Code Playgroud)


ror*_*ryf 0

我过去遇到过完全相同的问题,我发现解决该问题的唯一方法是将回调添加到 iframe 页面中。当然,只有当您可以控制 iframe 内容时,这才有效。

  • 我没有否决你,但我想你被否决是因为你提出了他说他不能做的事情——他确实明确表示,“我无法控制 IFRAME 中的内容,所以我不能”不要从那里触发回调。” (23认同)