Привязать document.ready к всплывающему окну - PullRequest
2 голосов
/ 17 ноября 2011

Из-за способа, которым jQuery связывает событие document.ready, простой код не должен быть:

var w = window.open(someSameOriginLocation,'');
$(w).ready(function () { //alternatively selector could be $(w.document)
  console.log('popout ready');
});

Проблемы

  • обратный вызов выполняется, когда родительское окно готово, а не дочернее
  • в обратном вызове this является ссылкой на w.opener.document

Существует ли достаточно простой кросс-браузерный способ привязки события ready (или аналогичного) к другому контексту окна с помощью jQuery?

Ответы [ 2 ]

0 голосов
/ 17 августа 2016

Когда я задавал этот вопрос около 5 лет назад, я не слышал об обещаниях. JQuery 1.7 был недавно выпущен, а Deferred был представлен в 1.5 ранее в этом году. Это предшествовало спецификации Promises/A+, которая была выпущена чуть более года спустя.

Я говорю это все потому, что в то время у меня не было возможности узнать $(document).ready(...) jQuery, как это было.

Он был связан как событие и воспринимал обратный вызов как событие, а API-интерфейс jQuery рассматривал его как событие, поэтому я ошибочно предположил, что это событие, хотя и специальное.

Документ готов не является событием. Это обещание.

Итак, со всем, что было сказано, моя ошибка заключалась в попытке последовать примеру jQuery и создать необычное событие, когда я должен был использовать обещание (не говоря уже о том, что их еще не было в мире JS).


Учитывая все вышесказанное, поддержка document.ready -подобного поведения для любой ссылки на окно в современных браузерах довольно проста. У меня есть преимущество времени в том, что многие старые проблемы были исправлены, а новые функции браузера (такие как Promise) значительно сокращают усилия по реализации функции ready.

Мое решение этой проблемы выглядит так:

function ready(win) {
    return new Promise(function (resolve) {
        function checkReady() {
            if (win.document.readyState === 'complete') {
                resolve();
            }
        }

        win.document.addEventListener('DOMContentLoaded', checkReady, false);
        win.addEventListener('load', checkReady, false);
        checkReady();
    });
}

и может использоваться как:

ready(window).then(function () {
  //...do stuff
});

или если вы используете window.open:

ready(open('/your/file.html', ...)).then(function () {
  //.../your/file.html is ready
});
0 голосов
/ 18 ноября 2011

Политика безопасности JavaScript не допускает этого.Например, вы получаете консольную ошибку

Unsafe JavaScript attempt to access frame with URL http://www.example.com/ from frame with URL http://www.example.org/. Domains, protocols and ports must match.

Необходимо сделать паузу между вызовом window.open и настройкой функции onload этого же окна.Сразу после вызова window.open это окно не имеет свойств.Возможно, вы должны делать это с setInterval несколько раз (не забудьте затем clearInterval)
Попробуйте это в jsfiddle (это мое лучшее предположение)

function func() {

    var w = window.open('http://fiddle.jshell.net/','windowname');

    setTimeout(function() {
        w.onload = function () {
            $(w).ready(function() {
                console.log(w.name)
            });
        };
    },1000)
}

http://jsfiddle.net/HerrSerker/fTjTr/8/

...