Обнаружение поддержки onbeforeunload

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

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

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
20
0
25 148
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

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

...так далее.

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

Другой подход, получите тип

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

{
alert("hello functionality!");
}

с каким браузером вы это тестируете?

curtisk 01.10.2008 21:38

все они, IE, Opera, Safari, Firefox, ваш код не работает ни в одном браузере, если (typeof window.onbeforeunload! = 'undefined') близок, но не работает в FF

jansokoly 01.10.2008 21:50

alert('onbeforeunload' in window);

Предупреждает "истина", если 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, так что это работает.

почти отлично работает в IE, Opera и Safari, но FF дает мне false, что не кажется правильным

jansokoly 01.10.2008 21:47

Извините, я думал, что он работает надежно, потому что я не знал, что Firefox поддерживается до выгрузки.

Grant Wagner 01.10.2008 21:55

Firefox не поддерживает такой вывод, но позволяет определить «до выгрузки», установив соответствующий атрибут для элемента. var el = document.createElement ('div'); el.setAttribute ('перед загрузкой', ''); тип эл. на перед разгрузкой; // "функция"

daniellmb 05.12.2010 10:07

У меня это не сработало в iOS Safari. Он скажет, что событие beforeunload поддерживается, даже если это не так.

ajaybc 11.01.2017 10:57

Крустер,

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

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

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

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

Спасибо, дружище, но это всего лишь теория - посмотрите другие ответы на эти вопросы, и вы найдете почти идеальные решения. Так что меня действительно не волнует, предлагает ли DOM какой-то интерфейс или нет. На самом деле есть надежные способы, как это проверить, это важно. Да, кстати, только Opera не хватает поддержки.

jansokoly 06.10.2008 17:36

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

Ответ принят как подходящий

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

Редактировать: этот метод сейчас используется в jQuery, Prototype.js, Modernizr и, вероятно, в других скриптах и ​​библиотеках.

Сайт, на который есть ссылка выше, находится внизу? У меня не работает, но я нашел кешированная версия.

regularmike 07.05.2012 21:55

Предупреждение: я написал комментарий к страница @ kangax, в частности, о том, что onbeforeunload определяется как поддерживаемый в Mobile Safari, хотя это на самом деле не работает надежно.

Peter V. Mørch 07.08.2013 14:43

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

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

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

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

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

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

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

Далее мы будем использовать localStorage (поддерживается во всех браузерах, которые мне небезразличны). about - см. 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() работал даже на первой странице. Но мне это было не нужно, поэтому я не вставил это в свою демонстрацию.

Я вижу, что это очень старый поток, но принятый ответ неправильно определяет поддержку 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.

onbeforeunload по умолчанию всегда имеет значение null. Если вы установите функцию onbeforeunload, она всегда будет функцией. Это не значит, что он сработает. Я не знаю то, что вы тестировали, но это не сработает. Единственный способ здесь - определение устройства iOS или метод Питера В. Мёрха.

hexalys 30.11.2014 11:42

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

Однако все современные немобильные браузеры поддерживают его. Поэтому вы можете просто проверить, является ли браузер мобильным.

Для решения проблемы использую:

var isMobile = navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/iPhone|iPad|iPod/i) || navigator.userAgent.match(/Opera Mini/i) || navigator.userAgent.match(/IEMobile/i);
if (isMobile)
{
    window.addEventListener("visibilitychange", function(e)
    {
        if (document.visibilityState == 'hidden')
        {
            console.info("beforeunload");
            location.reload();
        }
    });
}
else
{
    window.addEventListener("beforeunload", function(e)
    {
        console.info("beforeunload");
    });
}

Другие вопросы по теме