window.onbeforeunload не работает на iPad?


84

Кто-нибудь знает, onbeforeunloadподдерживается ли мероприятие на iPad и / или есть ли другой способ его использования?

Я перепробовал почти все, и похоже, что onbeforeunloadсобытие никогда не запускается на iPad (браузер Safari).

В частности, это то, что я пробовал:

  • window.onbeforeunload = function(event) { event.returnValue = 'test'; }
  • window.onbeforeunload = function(event) { return 'test'; }
  • (оба вышеперечисленного вместе)
  • window.onbeforeunload = function(event) { alert('test')'; }
  • (все вышеперечисленные функции, но внутри <body onbeforeunload="...">

Все это работает в FF и Safari на ПК, но не на iPad.

Кроме того, я сделал следующее сразу после загрузки страницы:

alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);

Соответственно, результаты таковы:

  • true
  • object
  • null

Итак, у браузера есть свойство, но по какой-то причине оно не запускается.

Я пытаюсь уйти со страницы, нажимая кнопки «Назад» и «Вперед», выполняя поиск в Google на верхней панели, изменяя местоположение в адресной строке и щелкая закладку.

Кто-нибудь знает, что происходит? Буду очень признателен за любой вклад.

благодаря


Спасибо вам обоим за ваш вклад. Наверное, это одна из причин, о которых вы упомянули. К сожалению, от Apple нет официальной документации относительно этого и других ограничений. Надеюсь, они придумают более творческий способ включения этой функции, предотвращая ее злонамеренное использование. Я очень часто слышу, что люди случайно касаются страницы и теряют все данные, которые они ввели в форму.
Art Zambrano

Вы пробовали использовать addEventListener()?
Hello71

2
Я почти уверен, beforeunloadчто не работает в Safari на iOS. :-( Возможно, это не то, что вы ищете, но у меня есть предложение, как надежно проверить работоспособностьbeforeunload
Питер В. Мёрч

1
3 марта 2016 года The window.onbeforeunload = function(event) { event.returnValue = 'test'; }не работает ни в Chrome, ни в Safari iOS 9.2.1. Мне очень нравится, onbeforeunloadпотому что страница не меняется, если я нажимаю "Отмена".
vanduc1102 01

1
Это событие должно поддерживаться в мобильных устройствах Iphone / Ipad и IOS. Это МАССИВНО влияет на время нахождения на сайте / аналитику пользователей. Он работает во всех браузерах и настольных компьютерах, кроме мобильных устройств IOS. saleemkce.github.io/timeonsite
webblover

Ответы:


20

Я обнаружил, что событие onunload () действительно срабатывает. Его поведение несколько странное; все, что у вас есть в вашей функции обратного вызова, прикрепленной к событию, фактически запускается после загрузки новой страницы в фоновом режиме (вы еще не можете сказать, что она загружена, но регистрация сервера покажет, что она есть).

Что еще более странно, если у вас есть вызов confirm () в onunload () и пользователь щелкнул ссылку, чтобы перейти в другое место, значит, вы в деле. Если, однако, пользователь закрывает вкладку браузера iPad Safari, событие onunload () срабатывает, но в ответ на ваш confirm () будет неявная отмена.


Ха, похоже, эта причуда подтверждения (что вторая страница нажимается до сообщения подтверждения) верна не только для мобильного сафари, но и для firefox (и, возможно, других). Ты просто взорвал мне голову.
Амальговинус 03

4
unloadмероприятие устарело в пользу pagehideсм. developer.apple.com/library/ios/documentation/AppleApplications/…
sol0mka 09

1
@ sol0mka: Вот и все, чувак! Большой! В моем случае следующий код выполнил свою работу, насколько я могу видеть для всех моих браузеров И iOS: $ (window) .on ('beforeunload pagehide', function () {// мои вещи, которые должны быть выполнены на странице изменение } ); В моих глазах это должен быть принятый ответ.
Гаравани

18

Этот фрагмент JavaScript работает для меня в Safari и Chrome на ipad и iphone, а также в настольных / портативных / других браузерах:

var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";

window.addEventListener(eventName, function (event) { 
    window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
    ...
} );

1
Он может поймать событие, но как вы можете вызвать запрос на подтверждение? Использование return 'test';подобного оператору не работает ..
user2335065 05

Спасибо, я пропустил это в исходном вопросе. Я специально не тестировал это на iOS, но, возможно, добавление этой дополнительной строки сработает: window.event.cancelBubble = true; Добавлю к своему ответу
Danger

2
Спасибо, но, к сожалению, это не работает ... Я попытался поместить в него alert (), кажется, новая страница начала загружаться до того, как сработает alert (). См. Также это: stackoverflow.com/questions/3239834/…
user2335065 08

@ user2335065 нашли ли вы какое-либо решение для того же?
Neeraj Rathod

ребята, вы нашли какое-нибудь решение, чтобы показать запрос подтверждения перед тем, как покинуть страницу? Это отлично работает во всех браузерах, кроме сафари для iOS. Я тоже пробовал событие pagehide, но у меня это не сработало. Заранее спасибо.
Рахул

6

Только компания Apple будет знать наверняка, но мне кажется, что они намеренно не включили эту функцию в мобильном Safari, так как он чаще всего используется тенистыми символов, чтобы заставить вас остаться на своем сайте или выскочит много порно / рекламных окон.


56
Или, вы знаете, сохраните изменения автоматически, чтобы они не потерялись только из-за того, что вы случайно нажали не то место.
Joel Mueller

4
Я не сказал, что это недопустимое использование, я просто сказал, что это наиболее частое использование.
Charles Boyung

3
@JoelMueller: Ваш комментарий должен быть принятым ответом :)
sanchez

1
@JoelMueller Это как раз мой вариант использования. Grrr @ apple
user2808054

@JoelMueller, не могли бы вы поделиться любым официальным документом, в котором мы можем обратиться к заявлению о том, что мобильное сафари сохраняет изменения автоматически.
Neeraj Rathod

3

В WebKit есть известная ошибка с onbeforeunload. Я считаю, что это исправлено в последней бета-версии Chrome 5, но вполне возможно, что браузер iPad создан на основе версии WebKit, в которой нет исправления.

Связанный отчет об ошибке Chrome .


2
Я запутался или эта ошибка все еще существует в браузере iPad?
Питер,


2

https://code.google.com/p/chromium/issues/detail?id=97035

видеть слышать.

предупреждения больше не допускаются во время событий закрытия страницы (перед выгрузкой, выгрузкой, скрытием страницы).

Я думаю, что предупреждения, подсказки, подтверждения и другие подобные действия также больше не разрешены.


2

Вот решение, которое должно работать во всех современных браузерах:

var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
    if (unloaded)
        return;
    unloaded = true;
    console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
    if (document.visibilityState == 'hidden')
    {
        if (unloaded)
            return;
        unloaded = true;
        console.log("beforeUnload");
    }
});

Мобильные браузеры, как правило, не поддерживают, beforeunloadпотому что браузер может перейти в фоновый режим, не выгружая страницу, а затем быть убитым операционной системой в любое время.

Большинство настольных браузеров содержат ошибку, из- visibilityStateза которой не вызывается при выгрузке документа. Смотрите: здесь .

Поэтому важно включить оба события, чтобы охватить все сценарии.

NB

Я использовал console.logвместо этого alertв моем примере, потому что он alertбудет заблокирован некоторыми браузерами при вызове из beforeunloadили visibilitychange.


1

Если вам просто нужно знать, осталась ли страница, вы можете использовать document.unload. Он отлично работает в браузерах ios. Если вы увидите в документации Apple, вы обнаружите, что она устарела, и они рекомендуют использовать document.pagehide


да, это событие запускается в сафари, но запрос подтверждения не появляется, как в хроме.
Рахул
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.