我很惊讶地发现以下似乎没有效果,因为DOMContentLoaded事件没有触发(this.els
是元素的对象)。
this.els.stage_ifr.prop('src', 'templates/'+ee.globals.creating+'/item'+this.id);
this.els.stage_ifr[0].addEventListener('DOMContentLoaded', function() {
alert('loaded!');
}, false);
页面加载到iframe中,但没有回调。但是,DOM级别onload
可以正常工作。
this.els.stage_ifr[0].onload = function() { alert('loaded!'); }; //<-- fires
解决方法是在父页面中准备一个全局可访问的jQuery延迟对象,并通过从调用iframe的页面触发的DOM-ready事件解决它,而不是从父级调用DOM-ready。
Paraent页面:
dfd = new $.Deferred;
dfd.done(function() { alert("frame page's DOM is ready!"); });
框架页面:
$(function() { window.parent.dfd.resolve(); });
尽管如此,知道第一种方法是什么还是很好......
答案 0 :(得分:17)
在回答this question的过程中,我发现了DOMContentLoaded
事件监听器无法正常工作的原因。在我看来,你有两个问题。
首先,您正在尝试在iFrame上监听DOMContentLoaded
事件。这不是一个iFrame事件。这是一个文件活动。因此,您必须进入iFrame才能获取contentWindow,然后从中获取文档。这导致了第二个问题。
其次,当首次创建iFrame时,它中有一个虚拟document
,它与通过.src
属性加载动态内容时最终会出现的文档不同。所以,即使你这样做了:
this.els.stage_ifr.contentWindow.document
要在iFrame中获取文档,它不一定是正确的文档,因此DOMContentLoaded
事件不会触发它(我在Chrome中看到过这种行为)。
MDN说,可以在iFrame本身上监听DOMFrameContentLoaded
事件,这与基础文档实际获得DOMContentLoaded
的时间相对应。不幸的是,我无法在任何浏览器中使用此活动。所以,在这个时刻,我所知道的唯一解决方法是从iFrame本身触发load事件,它可以监听自己的DOMContentLoaded
事件(如果需要,它可以调用父窗口) be)或只是听iFrame对象上的load
事件,并知道在iFrame中的样式表和图像等资源也被加载之前它不会被激活。
无论如何,我想我会解释你的初始代码发生了什么,并提供另一个解决方案,即使这个问题是在一年多前发布的(虽然从未回答)。
<强>更新强>
我开发了一种跟踪DOMContentLoaded
的方法,该方法用于加载与其父级相同来源的iFrame。您可以看到代码here。
答案 1 :(得分:5)
尝试不同的选项后,我发现以下代码适用于我:
var iframe = document.getElementById("app-frame-id");
iframe.contentWindow.addEventListener("DOMContentLoaded", onFrameDOMContentLoaded, true);
function onFrameDOMContentLoaded () {
console.log("DOMContentLoaded");
};
答案 2 :(得分:1)
这可能更像是一个黑客,但帮助我解决了类似的问题。
我现在正在收听onmouseenter
帧内容。
此事件在load
之前触发(如果用户移动鼠标)。但在我的情况下,我需要用于初始化上下文菜单的事件,无论如何使用鼠标是一个先决条件。
当鼠标下的帧内容发生变化时,它甚至会触发。
答案 3 :(得分:1)
如果您的页面和iframe 位于同一域上,则必须先等待原始页面触发DOMContentLoaded
,然后将DOMContentLoaded
事件监听器附加到iframe的Window
(不是Document
)。
鉴于您的iframe如下,
<iframe id="iframe-id" name="iframe-name" src="..."></iframe>
下一个代码段将使您能够参与iframe的DOMContentLoaded
事件:
document.addEventListener('DOMContentLoaded', function () {
var iframeWindow = frames['iframe-name'];
// var iframeWindow = document.querySelector('#iframe-id').contentWindow
// var iframeWindow = document.getElementById('iframe-id').contentWindow
iframeWindow.addEventListener('DOMContentLoaded', function () {
console.log('iframe DOM is loaded!');
});
});