Обнаружение браузеров, не поддерживающих onunload/onbeforeunload

Кажется, что из всех браузеров только Opera не поддерживает события onunload/onbeforeunload. (Прошло пятнадцать лет, Opera!) Решения этой проблемы обсуждались много раз, например, здесь: поддержка onbeforeunload обнаружение

К сожалению, начиная с Opera 11.51, ("onbeforeunload" in window) == true, но фактическое событие onbeforeunload никогда не выполняется!

Моему веб-приложению необходимо отправлять данные на сервер, когда пользователь покидает страницу; Я использую для этого синхронный запрос ajax. Похоже, мне пришлось прибегнуть к кнопке «Сохранить» где-то на странице, чтобы скрыть проблемы с Opera. Однако я не хочу, чтобы эта кнопка смущала пользователей, чьи браузеры поддерживают автоматическое сохранение через ajax, поэтому мне бы очень хотелось, чтобы эта кнопка отображалась только в Opera.

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


person Unknown artist    schedule 23.09.2011    source источник
comment
почему бы не использовать onuload для Opera?   -  person c69    schedule 23.09.2011
comment
body.onunload работает в Opera 11.5, если вы не звоните window.location.reload()   -  person Lyth    schedule 23.09.2011
comment
<body onunload = 'alert("test")'>, body.onunload = function() {alert("test")}; и body.unload(function() {alert("test")}); не работают на моей машине. Opera 11.51, без надстроек, Windows 7 64bit.   -  person Unknown artist    schedule 23.09.2011
comment
Вы обновляете/перезагружаете страницу или переходите на другую? <body onunload="alert('!')"><p onclick="window.location.reload();">Click here to reload</p><p><a href="http://ya.ru">Get away</a></p></body> - У меня работает onunload в этом случае при выходе со страницы. В любом случае, вы не получите код, выполненный в Opera, если закроете страницу/приложение, поэтому лучшим способом может быть реализация какого-либо другого способа сохранения данных. Как насчет локального хранилища?   -  person Lyth    schedule 23.09.2011
comment
Да, вы абсолютно правы, моя проблема в том, что мне это нужно для сохранения данных во всех случаях, и я тестировал это, в основном закрывая вкладку. Локальное хранилище — хорошая идея, но, насколько я понимаю, изменения, сделанные в Opera, не будут видны, если пользователь зайдет из другого браузера. Кроме того, мы все Русские здесь, или дело в часовом поясе, в котором спят американцы? :D   -  person Unknown artist    schedule 23.09.2011
comment
Можете ли вы дать нам ссылку на страницу, где («onbeforeunload» в окне) возвращает true в Opera? Здесь он возвращает правильный и ожидаемый «false».   -  person hallvors    schedule 13.04.2012


Ответы (4)


Я не могу воспроизвести ваш вывод о том, что 'onbeforeunload' in window равно true в Opera 11.5x. Это лучший способ сделать это, и он все еще должен работать. Вы уверены, что не оставили где-то какое-то определение, например. ты написал

onbeforeunload = function (){ ... }

позже в том же скрипте, который выполняет обнаружение функции? Если вы сделаете alert(window.onbeforeunload), что вы увидите? Не поделитесь ссылкой на страницу с проблемой?

person hallvors    schedule 26.09.2011
comment
Я могу подтвердить, я только что проверил в Opera 11.62, и alert('onbeforeunload' in window) действительно говорит false. Я даже проверил с opera:config > User Agent > Spoof UserAgent ID, установленным на разные значения, но для меня это всегда ложно. - person jakub.g; 05.04.2012
comment
В Opera 15 я получаю true (и это правильно, теперь это поддерживается в движке на основе Webkit). Я также могу проверить в 12.15, что это ложь. - person wojo; 03.07.2013

Опера облажалась с этим псом. Я обнаруживаю Opera, ища window.opera, и если он существует, я отказываю Opera в том, с чем она не может справиться.

Я думаю, что использовать выгрузку бесполезно, потому что это происходит слишком поздно в игре. Иногда onbeforeunload — единственное, что помогает. Еще раз, я просто ищу оперу на объекте окна, и, если он существует, отрицаю то, что он не может сделать. :)

PPK говорит об этом здесь: http://www.quirksmode.org/js/detect.html

person Tom    schedule 24.09.2011
comment
Искать window.opera - не лучший способ сделать это. Ищите функции, а не браузеры :) - person hallvors; 09.05.2012

Для тех, кто натыкается на этот пост, это фрагмент кода, который я использую для обнаружения поддержки onbeforeunload, и если браузер не поддерживает ее, я переключаюсь на onunload (обратите внимание на использование jquery, очевидно, не требуется). В моем случае я использую этот код (и немного больше), чтобы проверить, активны ли еще какие-либо запросы AJAX, и остановить переход пользователя. Имейте в виду, что использование onunload не идеально, потому что браузер по-прежнему будет уходить со страницы, но, по крайней мере, это дает вам возможность предупредить пользователя о том, что данные могли быть потеряны, и им следует вернуться и проверить.

Вы заметите, что я использую функцию isEventSupported(), доступную по адресу https://github.com/kangax/iseventsupported для поддержки кросс-браузерного обнаружения доступных событий.

// If the browser supports 'onbeforeunload'
if (isEventSupported('beforeunload', window)) {
  $(window).on('beforeunload', function(){
    return 'This page is still sending or receiving data from our server, if you recently submitted data on this page please wait a little longer before leaving.';
  });
} 
// The browser doesn't support 'onbeforeunload' (Such as Opera), do the next best thing 'onunload'.
else {
  $(window).on('unload', function(){
    alert('This page was still sending or receiving data from our server when you navigated away from it, we would recommend navigating back to the page and ensure your data was submitted.');
  });
}
person Sean Bannister    schedule 16.09.2012

См. мой ответ на аналогичный/дублированный вопрос. По сути, он устанавливает обнаружение на самой первой странице вашего домена и сохраняет результат обнаружения для всех последующих страниц в localStorage. Включая рабочий пример кода.

person Peter V. Mørch    schedule 08.08.2013