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)
Neo*_*Neo 35
我正在使用jQuery,令人惊讶的是,这似乎加载,因为我刚测试并加载了一个沉重的页面,我没有收到警报几秒钟,直到我看到iframe加载:
$('#the_iframe').load(function(){
alert('loaded!');
});
Run Code Online (Sandbox Code Playgroud)
因此,如果您不想使用jQuery,请查看其源代码并查看此函数是否与iframe DOM元素的行为不同,稍后我会自己查看它,因为我感兴趣并在此处发布.此外,我只测试了最新的铬.
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)
如果将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)
当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)
希望这可以帮助.
如果 iFrame 已加载,此函数将立即运行您的回调函数,或者等到 iFrame 完全加载。
这还解决了以下问题:
Chrome 使用一个页面初始化每个 iFrame,about:blank该页面将具有readyState == "complete". 稍后,它会将 `about:blank 替换为实际的 iframe src 值。因此,readyState的初始值不会代表实际iFrame的readyState。因此,除了检查readyState值之外,该函数还解决了about:blank问题。
DOMContentLoaded事件不适用于 iFrame。因此,load如果 iFrame 尚未加载,它会使用该事件来运行回调函数。该load事件相当于readyState == "complete"用于检查 iFrame 是否已加载的事件。因此,在任何情况下,回调函数都会在 iFrame 完全加载后运行。
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)
我过去遇到过完全相同的问题,我发现解决该问题的唯一方法是将回调添加到 iframe 页面中。当然,只有当您可以控制 iframe 内容时,这才有效。
| 归档时间: |
|
| 查看次数: |
257960 次 |
| 最近记录: |