Свяжите документ.готов к появлению всплывающего окна


Из-за способа, которым 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 2

2 ответа:

Когда я задавал этот вопрос около 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
});

Политика безопасности 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.

Необходимо, чтобы у вас была пауза между вызовом окна.Открытие и настройка функции onload этого же окна. Сразу после окна.открыть вызов это окно не имеет свойств. Возможно, вы должны сделать это с 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/