Есть ли способ использовать window.onbeforeunload на Mobile Safari для устройств iOS?
Похоже, Apple отключила событие window.onbeforeunload для устройств iOS (iPhone, iPad, iPod Touch). К сожалению, я не могу найти документацию о том, почему это событие не работает в Mobile Safari.
Кто-нибудь знает, есть ли надежная альтернатива этой функции? Браузер Android, похоже, прекрасно его поддерживает, а настольное приложение Safari также поддерживает событие onbeforeunload без проблем.
2 ответа
Я вижу, что это старый вопрос, но я недавно столкнулся с этой проблемой.
я использую window.unload
и он отлично работает в браузерах IOS (хотя, если вы посмотрите на документацию Apple, она устарела, и они рекомендуют использовать document.pagehide
)
Основываясь на ответе Ксавьера, я разработал решение в этом направлении:
function doStuff() {
// here goes your logic
}
function isSafariMobile() {
return navigator && /Safari/.test(navigator.userAgent) && /iPhone|iPad/.test(navigator.userAgent)
}
function addWatcherToLinks(baseNode) {
if (!baseNode || !baseNode.querySelectorAll) { return; } // ignore comments, text, etc.
for (const link of baseNode.querySelectorAll("a")) {
link.addEventListener('click', doStuff);
}
for (const form of baseNode.querySelectorAll("form")) {
form.addEventListener('submit', doStuff);
}
}
// ...when the page loads...
// we watch the page for beforeunload to call doStuff
// Since Safari mobile does not support this, we attach a listener (watcher) to each link and form and then call doStuff.
// Also, we add such a watcher to all new incoming nodes (DOMNodeInserted).
if (isSafariMobile()) {
addWatcherToLinks(document);
window.addEventListener("DOMNodeInserted", (event) => { addWatcherToLinks(event.target); }, false);
} else {
window.addEventListener('beforeunload', doStuff);
}
У этого решения есть некоторые ограничения. Самый большой из них заключается в том, что он прикрепляется ко всем формам и всем ссылкам. Иногда это может быть нежелательно. Если вам это нужно, вы можете пропустить некоторые узлы (например, пометить их определеннымdata-
атрибут).
Если вам это действительно нужно, вы не можете просто получить все ссылки, формы и DOM-объекты, у которых есть обработчик, изменяющий URL-адрес, и заставить их ждать, пока вы не сделаете то, что хотите. Для ссылок вы получите их с помощью getElementsByTagName, проверьте, начинается ли href с чего-либо, кроме #, и просто добавьте свою функцию onbeforeunload add onclick (которая будет вызвана до того, как href будет просматриваться). То же самое для форм, но с отправкой. И наконец, для элементов, изменяющих href с помощью JavaScript, вы должны убедиться, что при добавлении lsitener, который вы вызываете своей функцией onbeforeunlaod (или, если вы используете прослушиватели DOM0 или DOM1, вы можете просто добавить некоторый класс и затем использовать глобальный скрипт это проверяет все элементы с классом и добавляет его к слушателю события с закрытием.
Но, как правило, вы должны избегать использования этого события (возможно, с помощью файлов cookie для хранения того, что вы хотите отправлять каждые x секунд, и, в худшем случае, для просмотра его в следующий раз, когда пользователь загружает страницу и в лучшем случае сможет отправлять Ajax-запрос при onbeforeunload или onunload, который, даже если он отправляет только заголовки http, позволит вам получить то, что вы хотите).
У меня была такая же проблема. Кажется, что браузер сафари в iphone запускает только события фокусировки и размытия, и почти каждое другое событие не запускается, например (pagehide, pageshow, изменение видимости), но хорошие новости заключаются в том, что событие фокусировки и размытия поддерживается и запускается на мобильных устройствах iphone, ipad и android также.
window.addEventListener('focus', function(){
// do stuff
});
window.addEventListener('blur', function(){
// do stuff
});
надеюсь, что это поможет кому-нибудь.