Как использовать MutationObserver во вновь созданном окне

Я хочу использовать MutationObserver для отслеживания изменений DOM в окне, которое я создаю с помощью window.open. У меня есть следующий код:

var newWin = window.open('/somepath');
var observerConfig = {
    childList: true,
    subtree: true,
    attributes: false,
    characterData: false
};
var obs = new newWin.MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (!mutation.addedNodes) return;
        mutation.addedNodes.forEach(function(addedNode) {
            console.log(addedNode);
        });
    })
});
obs.observe(newWin.document, observerConfig);

Я ожидал увидеть некоторые недавно добавленные узлы, зарегистрированные в консоли (как я получил, когда я отслеживал исходное окно таким же образом, тот же наблюдатель), но я ничего не получаю. Я что-то упускаю?


person benams    schedule 01.01.2018    source источник
comment
Пфф, просто наблюдайте newWin.document.   -  person wOxxOm    schedule 01.01.2018
comment
@wOxxOm Я пробовал это, и, не дожидаясь события load во вновь созданном окне, это не сработало. Я что-то упускаю? (проверено на Chrome и Firefox)   -  person Sébastien    schedule 02.01.2018
comment
Попробуйте использовать new newWin.MutationObserver   -  person wOxxOm    schedule 02.01.2018
comment
@wOxxOm, я изменил свой код в соответствии с вашими предложениями (вы можете увидеть отредактированный вопрос), и у меня все еще нет журналов. Когда я просто заменяю первую строку на var newWin = window;, я вижу, что новые добавления узлов регистрируются, как и ожидалось, поэтому кажется, что проблема заключается в window.open.   -  person benams    schedule 03.01.2018
comment
Ну, я думаю, это не работает с window.open.   -  person wOxxOm    schedule 03.01.2018
comment
На самом деле это работает с window.open, но только когда я использую прослушиватель событий, как рекомендовал @Sébastien...   -  person benams    schedule 04.01.2018


Ответы (1)


Это та же проблема, с которой вы столкнетесь при использовании JavaScript (например, из сценария в <head>) для изменения DOM текущего документа до того, как DOM будет загружен: вы попытаетесь получить доступ к элементам, которые не существуют в памяти в момент в это время.

Вы должны использовать событие DOMContentLoaded для запуска обратного вызова, когда DOM загружен и готов к управлению.

Точно так же, когда вы пытаетесь получить доступ к DOM нового окна, загрузка этого окна может быть еще не завершена.

Вы должны обернуть вызов obs.observe в прослушиватель событий load:

newWin.addEventListener('load', function() {
    obs.observe(newWin.document.body, observerConfig);
}, true);

Таким образом, когда вы начинаете наблюдать за телом, вы уверены, что оно действительно существует!

person Sébastien    schedule 01.01.2018