当 IFRAME 加载完成时,是否进行 Javascript 回调?

当 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 加载之前进行,因此该回调没有返回数据。

278653 次浏览

我过去也遇到过同样的问题,我发现解决它的唯一方法是在 iframe 页面中添加回调。当然,这只有在您可以控制 iframe 内容的情况下才有效。

我在我的项目中有一个类似的代码,它工作得很好。 根据您的功能调整我的代码,解决方案可能如下:

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. 你应该用它来对付 body 元素 2. 您已经从页面 DOM 中删除了 iframe

首先,使用函数名 请求,听起来像是在尝试跨站点请求——如果这是正确的,那么您将无法读取 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);
});

当 word docs 和 pdf 等文档流到 iframe 并找到一个非常好的解决方案时,我必须这样做。关键是在 iframe 上处理 onreadystatechanged事件。

让我们假设你的帧的名字是“ myIframe”。首先在代码启动阶段(在 iframe 之后的任何地方我都是内联的)添加类似这样的东西来注册事件处理程序:

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

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

下面是一个如何获得完整状态的例子:

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

我认为加载事件是正确的。 不正确的是用于从 iframe 内容域检索内容的方法。

您需要的是加载到 iframe 中的页面的 html,而不是 iframe 对象的 html。

您需要做的是使用 iFrameObj.contentDocument访问内容文档。 这将返回在 iframe 中加载的页面的域(如果它与当前页面在同一个域上的话)。

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

我测试过火狐和歌剧。

然后我认为你可以检索你的数据与 $(childDom).html()$(childDom).find('some selector') ...

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>

我也遇到过类似的问题。我所做的就是使用一个叫做 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();


});


});

看起来好像你删除你的 iFrame 之前,你从它抓取 HTML。现在,我确实看到了一个问题: p

希望这对你有帮助:)。

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

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

因此,如果您不想使用 jQuery,那么查看一下它们的源代码,看看这个函数是否与 iframe DOM 元素有不同的行为,稍后我会在感兴趣的时候自己查看它,并在这里发布。而且我只测试了最新的铬合金。

我想隐藏等待的 spinner div 当 i 帧内容完全加载到 IE 时,我尝试了在 Stackoverflow 提到的所有解决方案。但是没有任何我想要的东西。

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

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

希望这个能帮上忙。

使用 onload属性将解决您的问题。

这里有一个例子。

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

Is this what you want?

Click here for more information.

如果 iFrame 已经加载或等待 iFrame 完全加载,则此函数将立即运行回调函数。

这也解决了以下问题:

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

  2. DOMContentLoaded事件对 iFrame 无效。因此,如果 iFrame 尚未加载,它将使用 load事件来运行回调函数。load事件等效于 readyState == "complete"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);
}
}