Плач, пока содержимое iframe не завершится sh перезагрузка - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть <iframe> с содержимым, разработанным (и разрешенным) для изменения кодом JS. В какой-то момент я хочу очистить содержимое iframe (т.е. загрузить его HTML из документа, указанного атрибутом src) и начать работать с новым DOM, как только он будет загружен.

Это кажется очень удобным для используйте функцию iframe.contentWindow.location.reload(). Он перезагружает весь внутренний документ и заменяет объекты iframe.contentWindow и iframe.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> и создать новый, но у этого подхода было еще больше проблем.

1 Ответ

0 голосов
/ 09 февраля 2020

Из-за ограничений, связанных с несколькими источниками, это будет работать только в том случае, если вы запускаете исходный и родительский фреймы из одного домена, однако вы должны иметь возможность использовать:

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, чтобы убедиться, что загрузка завершена. Функция вернет true или false в зависимости от того, успешно ли загружен iframe. При желании вы также можете запустить функцию в al oop после запроса перезагрузки iframe, пока загрузка iframe не завершится.

...