Свяжите документ.готов к появлению всплывающего окна
Из-за способа, которым 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 ответа:
Когда я задавал этот вопрос около 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) }