IFRAME加载完成后的Javascript回调?

时间:2008-10-02 19:21:45

标签: javascript events dom iframe

我需要在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);
    });
}

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

10 个答案:

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

答案 1 :(得分:35)

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

$('#the_iframe').load(function(){
    alert('loaded!');
});

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

答案 2 :(得分: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>

要进一步举例,请尝试将其用作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>

答案 3 :(得分:7)

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

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

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

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

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

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

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

希望这有帮助。

答案 5 :(得分:2)

我的项目中有类似的代码可以正常工作。 使我的代码适应您的功能,解决方案可能如下:

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

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

也许你有一个空的innerHTML因为(一个或两个原因):   1.你应该用它对抗身体元素   2.您已从页面DOM中删除了iframe

答案 6 :(得分:2)

我遇到了类似的问题。我做的是我使用了一个叫做jQuery的东西。你在javascript代码中做的是:

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

在您从中获取html之前,您似乎删除了iFrame。现在,我确实看到了一个问题:p

希望这会有所帮助:)。

答案 7 :(得分:1)

我认为加载事件是正确的。 什么是不对的是你用来从iframe内容dom中检索内容的方式。

你需要的是在iframe中加载的页面的html而不是iframe对象的html。

您需要做的是使用iFrameObj.contentDocument访问内容文档。 这将返回iframe中加载的页面的dom,如果它位于当前页面的同一个域中。

我会在删除iframe之前检索内容。

我在firefox和opera中测试过。

然后我认为您可以使用$(childDom).html()$(childDom).find('some selector') ...

来检索您的数据

答案 8 :(得分:0)

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

答案 9 :(得分:-1)

使用onload attrbute可以解决您的问题。

这是一个例子。

&#13;
&#13;
function a() {
alert("Your iframe has been loaded");
}
&#13;
<iframe src="https://stackoverflow.com" onload="a()"></iframe>
&#13;
&#13;
&#13;

这是你想要的吗?

Click here了解更多信息。