Что ж, «волшебное время», о котором вы говорите, вероятно, наступает тогда, когда DOM всплывающего окна загружен. Или это может быть, когда все (изображения, внешний CSS и т. Д.) Было загружено. Вы можете легко проверить это, добавив во всплывающее окно очень большую графику (сначала очистите кеш!). Если вы использовали Javascript Framework, например jQuery (или что-то подобное), вы могли бы использовать событие ready () (или что-то подобное), чтобы дождаться загрузки DOM перед проверкой смещения окна. Опасность в том, что обнаружение Safari работает противоречивым образом: DOM всплывающего окна никогда не будет готов () в Safari, потому что он даст вам действительный дескриптор для окна, которое вы пытаетесь открыть - независимо от того, открывается ли оно на самом деле или нет. (на самом деле, я считаю, что приведенный выше тестовый код всплывающего окна не будет работать для сафари.)
Я думаю, что лучшее, что вы можете сделать, - это обернуть свой тест в setTimeout () и дать всплывающему окну 3-5 секунд для полной загрузки перед запуском теста. Это не идеально, но должно работать как минимум в 95% случаев.
Вот код, который я использую для кросс-браузерного обнаружения, без части Chrome.
function _hasPopupBlocker(poppedWindow) {
var result = false;
try {
if (typeof poppedWindow == 'undefined') {
// Safari with popup blocker... leaves the popup window handle undefined
result = true;
}
else if (poppedWindow && poppedWindow.closed) {
// This happens if the user opens and closes the client window...
// Confusing because the handle is still available, but it's in a "closed" state.
// We're not saying that the window is not being blocked, we're just saying
// that the window has been closed before the test could be run.
result = false;
}
else if (poppedWindow && poppedWindow.test) {
// This is the actual test. The client window should be fine.
result = false;
}
else {
// Else we'll assume the window is not OK
result = true;
}
} catch (err) {
//if (console) {
// console.warn("Could not access popup window", err);
//}
}
return result;
}
Что я делаю, так это запускаю этот тест от родителя и оборачиваю его в setTimeout (), давая дочернему окну 3-5 секунд для загрузки. В дочернем окне нужно добавить тестовую функцию:
function test () {}
Детектор блокировщика всплывающих окон проверяет, существует ли функция «test» как член дочернего окна.
ДОБАВЛЕНО 15 ИЮНЯ 2015:
Я думаю, что современный способ справиться с этим - использовать window.postMessage (), чтобы дочерний элемент уведомлял родителя о том, что окно загружено. Подход аналогичен (ребенок сообщает родителям, что он загружен), но средства связи улучшились. Мне удалось сделать этот кросс-домен от ребенка:
$(window).load(function() {
this.opener.postMessage({'loaded': true}, "*");
this.close();
});
Родитель прослушивает это сообщение, используя:
$(window).on('message', function(event) {
alert(event.originalEvent.data.loaded)
});
Надеюсь это поможет.
person
Ringo
schedule
07.07.2009