Onbeforeunload поддержка обнаружения

Я хочу проверить, поддерживает ли текущий браузер событие onbeforeunload. Общий способ javascript для этого не работает:

if (window.onbeforeunload) {
    alert('yes');
}
else {
    alert('no');
}

Собственно, он проверяет, не привязан ли какой-либо обработчик к событию. Есть ли способ определить, поддерживается ли onbeforeunload без обнаружения конкретного имени браузера?

Ответ 1

Я писал о более или менее надежном выводе для обнаружения поддержки событий в современных браузерах некоторое время назад. Вы можете увидеть на демонстрационной странице, что "beforeunload" поддерживается, по крайней мере, Safari 4+, FF3.x + и IE.

Изменить. Этот метод теперь используется в jQuery, Prototype.js, Modernizr и, возможно, в других скриптах и ​​библиотеках.

Ответ 2

К сожалению ответ kangax не работает для Safari в iOS. В моем тестировании beforeunload поддерживался в каждом браузере, который я точно пробовал, кроме Safari в IOS: - (

Вместо этого я предлагаю другой подход:

Идея проста. На самом первом посещении страницы мы пока не знаем, если beforeunload поддерживается. Но на этой самой первой странице мы создали и unload и a beforeunload. Если срабатывает обработчик beforeunload, мы устанавливаем флаг, подтверждающий, что поддерживается beforeunload (фактически beforeunloadSupported = "yes"). Когда обработчик unload срабатывает, если флаг не был установлен, мы устанавливаем флаг beforeunload не поддерживается.

В дальнейшем мы будем использовать localStorage (поддерживается во всех браузерах, которые мне очень нравятся about - see http://caniuse.com/namevalue-storage), чтобы получить/установить флаг. Мы мог бы также использовать cookie, но я выбрал localStorage, потому что там не является основанием для отправки этой информации на веб-сервер по каждому запросу. Мы просто нужен флаг, который переживает перезагрузку страницы. Как только мы его однажды обнаружим, это будет оставаться навсегда.

С этим вы теперь можете позвонить isBeforeunloadSupported(), и он вам скажет.

(function($) {
    var field = 'beforeunloadSupported';
    if (window.localStorage &&
        window.localStorage.getItem &&
        window.localStorage.setItem &&
        ! window.localStorage.getItem(field)) {
        $(window).on('beforeunload', function () {
            window.localStorage.setItem(field, 'yes');
        });
        $(window).on('unload', function () {
            // If unload fires, and beforeunload hasn't set the field,
            // then beforeunload didn't fire and is therefore not
            // supported (cough * iPad * cough)
            if (! window.localStorage.getItem(field)) {
                window.localStorage.setItem(field, 'no');
            }
        });
    }
    window.isBeforeunloadSupported = function () {
        if (window.localStorage &&
            window.localStorage.getItem &&
            window.localStorage.getItem(field) &&
            window.localStorage.getItem(field) == "yes" ) {
            return true;
        } else {
            return false;
        }
    }
})(jQuery);

Вот полный jsfiddle с использованием примера.

Обратите внимание, что он будет обнаружен только на второй или любой последующей загрузке страницы на вашем сайте. Если вам важно, чтобы он работал на самой первой странице, вы можете загрузить iframe на этой странице с атрибутом src, указывающим на страницу в том же домене с обнаружением здесь, убедитесь, что она имеет и затем удалите его. Это должно гарантировать, что обнаружение выполнено так, что isBeforeunloadSupported() работает даже на первой странице. Но мне это не нужно, поэтому я не поместил это в свое демо.

Ответ 3

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

$(window).bind('unload', function(){
    alert('unload event');
});

window.onbeforeunload = function(){
    $(window).unbind('unload');
    return 'beforeunload event';
}

Это должно отменить событие unload, если происходит событие beforeunload. В противном случае он просто запустит разгрузку.

Ответ 4

alert('onbeforeunload' in window);

Оповещения "true", если onbeforeunload является свойством window (даже если оно равно null).

Это должно сделать то же самое:

var supportsOnbeforeunload = false;
for (var prop in window) {
    if (prop === 'onbeforeunload') {
    supportsOnbeforeunload = true;
    break;
    }
}
alert(supportsOnbeforeunload);

Наконец:

alert(typeof window.onbeforeunload != 'undefined');

Опять же, typeof window.onbeforeunload представляется "объектом", даже если он имеет значение null, поэтому это работает.

Ответ 5

Cruster,

"Предварительная загрузка" не определена в спецификации DOM-Events, это особенность, специфичная для IE. Я думаю, что он был создан для того, чтобы включить запуск перед стандартным событием "разгрузка". В других браузерах IE вы можете использовать прослушиватель событий "разгружать" фазы захвата, тем самым получая код, выполняемый до, например, события online для встроенного тела.

Кроме того, DOM не предлагает каких-либо интерфейсов для проверки поддержки определенного события, вы можете проверить только поддержку группы событий (MouseEvents, MutationEvents и т.д.).

Между тем вы также можете обратиться к спецификации DOM-Events http://www.w3.org/TR/DOM-Level-3-Events/events.html (к сожалению, не поддерживается в IE)

Надеемся, что эта информация поможет некоторым

Ответ 6

Разный подход, получите тип

if(typeof window.onbeforeunload == 'function')

{
alert("hello functionality!");
}

Ответ 7

onbeforeunload также поддерживается FF, поэтому тестирование для браузера не поможет.

Ответ 8

Я вижу, что это очень старый поток, но принятый ответ неправильно обнаруживает поддержку Safari на iOS, что заставило меня исследовать другие стратегии:

if ('onbeforeunload' in window && typeof window['onbeforeunload'] === 'function') {
  // onbeforeunload is supported
} else {
  // maybe bind to unload as a last resort
}

Вторая часть if-check необходима для Safari в iOS, у которой свойство имеет значение null.

Протестировано в браузерах Chrome 37, IE11, Firefox 32 и Safari для iOS 7.1

Ответ 9

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

if( $.browser.msie ) {
  alert( 'no' );
}

... и т.д..

$.browser.msie - это синтаксис jQuery, большинство фреймворков имеют аналогичные встроенные функции, так как они используют их настолько внутренне. Если вы не используете фреймворк, я бы предложил просто взглянуть на реализацию этих функций jQuery.