我惊讶地发现以下内容似乎不起作用,因为
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 级别 0
onload
是有效的。
this.els.stage_ifr[0].onload = function() { alert('loaded!'); }; //<-- fires
解决方法是在父页面中准备一个全局可访问的 jQuery 延迟对象,并通过从调用 iframe 的页面触发的 DOM-ready 事件来解析它,而不是从父页面监听 DOM-ready。
父页面:
dfd = new $.Deferred;
dfd.done(function() { alert("frame page's DOM is ready!"); });
框架页面:
$(function() { window.parent.dfd.resolve(); });
尽管如此,最好知道第一种方法的情况......
在回答这个问题的过程中,我发现了你的
DOMContentLoaded
事件监听器不起作用的原因。在我看来你有两个问题。
首先,您尝试监听 iFrame 本身上的
DOMContentLoaded
事件。这不是 iFrame 事件。这是一个文档事件。因此,您必须进入 iFrame 来获取 contentWindow,然后从中获取文档。这就引出了第二个问题。
其次,当首次创建 iFrame 时,其中有一个虚拟
document
,该文档与通过 .src
属性加载动态内容时最终出现的文档不同。所以,即使你这样做了:
this.els.stage_ifr.contentWindow.document
要获取 iFrame 中的文档,它不一定是正确的文档,因此
DOMContentLoaded
事件不会在其上触发(我在 Chrome 中看到过这种行为)。
MDN 表示可以监听 iFrame 本身上的
DOMFrameContentLoaded
事件,这将与底层文档实际获取 DOMContentLoaded
的时间相对应。不幸的是,我无法让此事件在任何浏览器中运行。因此,目前,我知道的唯一解决方法是从 iFrame 本身内部触发加载事件,它可以侦听自己的 DOMContentLoaded
事件(如果需要,它可以调用父窗口)或者只是侦听 iFrame 对象上的 load
事件,并知道在加载 iFrame 中的样式表和图像等资源之前它不会触发。
无论如何,我想我应该解释一下你的初始代码发生的一些事情,并提供另一个解决方案,即使这个问题是一年多前发布的(尽管从未得到回答)。
更新:
我开发了一种跟踪
DOMContentLoaded
的方法,用于加载与其父级具有相同来源的 iFrame。您可以在此处查看代码。
尝试不同的选项后,我发现以下代码适合我:
var iframe = document.getElementById("app-frame-id");
iframe.contentWindow.addEventListener("DOMContentLoaded", onFrameDOMContentLoaded, true);
function onFrameDOMContentLoaded () {
console.log("DOMContentLoaded");
};
如果您的页面和 iframe 位于同一域中,您必须首先等待原始页面触发
DOMContentLoaded
,然后在 iframe 的 DOMContentLoaded
(不是 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!');
});
});
这可能更像是一种黑客攻击,但帮助我解决了类似的问题。
我现在正在听
onmouseenter
的框架内容。
此事件在
load
之前触发(如果用户移动鼠标)。但就像我的情况一样,我需要初始化上下文菜单的事件,无论如何使用鼠标都是先决条件。
甚至当鼠标下的框架内容发生变化时也会触发。