首页 > 解决方案 > 一直哭到 iframe 内容完成重新加载

问题描述

我有一个<iframe>设计(并允许)由 JS 代码修改的内容。在某些时候,我想清除 iframe 的内容(即从src属性指向的文档中加载其 HTML)并在新 DOM 加载后立即开始对其进行操作。

使用该iframe.contentWindow.location.reload()功能似乎很方便。它重新加载整个内部文档并用新的替换iframe.contentWindowiframe.contentDocument对象。

问题是我无法DOMContentLoaded在新创建的文档上收听事件。iframe.contentDocument如果我在调用后立即添加一个侦听器reload(),它似乎附加到即将被销毁的旧文档对象。如果我在添加监听器之前等待一段时间,我有机会在事件触发后设置它并错过它。观察readyState文档的属性并没有帮助,因为它可以设置为"complete"文档尚未重新加载的时间以及文档重新加载并完成加载其内容的时间。

到目前为止,我能想出的最佳解决方案非常难看,需要主动轮询:

function reloadIframe(iframe) {
    iframe.contentWindow.dirty = true;
    iframe.contentWindow.location.reload();
}

function documentReady(iframe) {
    return new Promise(resolve => {
        setInterval(() => {
            if (
                !iframe.contentWindow.dirty &&  // check that this is not the old window instance
                iframe.contentDocument.readyState != "loading"
            ) {
                resolve();
            }
        }, CHECK_READY_INTERVAL);
    });
}

当窗口完成重新加载时获得通知的更简单方法是什么?

注意:我可以删除<iframe>元素本身并创建新元素,但这种方法有更多问题。

标签: javascriptiframedom-eventsreload

解决方案


由于跨域限制,这仅在您运行来自同一域的源框架和父框架时才有效,但是,您应该能够使用:

function documentReady(iframe) {
var doc = iframe.contentDocument || iframe.contentWindow.document;

    if ( doc.readyState  == 'complete' ) {
        iframe.contentWindow.onload = function() {
            return true;
        };
    } else {
        return false;
    }
}

这实际上将获取 iframe 文档并检查文档和所有子资源是否已完成加载。如果有,它将调用 onload 以验证它是否已完成加载。该函数将根据 iframe 是否已成功加载返回 true 或 false。如果需要,您还可以在请求 iframe 重新加载后循环运行该函数,直到 iframe 完成加载。


推荐阅读