Обнаружение закрытия браузера или вкладки

Существует ли какой-либо кросс-браузерный код JavaScript/jQuery для обнаружения закрытия браузера или вкладки браузера, но не из-за щелчка ссылки?

Ответ 1

Если вы правильно поняли, вы хотите знать, когда вкладка/окно эффективно закрывается. Ну, AFAIK единственный способ в Javascript обнаружить такие вещи onunload и onbeforeunload.

К сожалению (или, к счастью?), эти события также запускаются, когда вы покидаете сайт над кнопкой link или кнопкой браузера. Так что это лучший ответ, который я могу дать, я не думаю, что вы можете обнаружить чистый close в Javascript. Исправьте меня, если я ошибаюсь.

Ответ 2

Из Документация Firefox

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

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";

  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage;                            //Webkit, Safari, Chrome
});

Этот пример для обработки всех браузеров.

Ответ 3

Простое решение

window.onbeforeunload = function () {
    return "Do you really want to close?";
};

Ответ 4

<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">

var myclose = false;

function ConfirmClose()
{
    if (event.clientY < 0)
    {
        event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
        setTimeout('myclose=false',10);
        myclose=true;
    }
}

function HandleOnClose()
{
    if (myclose==true) 
    {
        //the url of your logout page which invalidate session on logout 
        location.replace('/contextpath/j_spring_security_logout') ;
    }   
}

//Это работает в IE7, если вы закрываете вкладку или браузер только с одной вкладкой

Ответ 5

Извините, я не смог добавить комментарий к одному из существующих ответов, но в случае, если вы хотели реализовать диалоговое окно с предупреждением, я просто хотел упомянуть, что любая функция обработчика событий имеет аргумент - событие. В вашем случае вы можете вызвать event.preventDefault(), чтобы запретить оставить страницу автоматически, а затем выпустить свой собственный диалог. Я считаю, что это лучший вариант, чем использование стандартного уродливого и небезопасного предупреждения(). Я лично реализовал свой собственный набор диалоговых окон на основе объекта kendoWindow (пользовательский интерфейс Telerik Kendo, который почти полностью открыт, за исключением kendoGrid и kendoEditor). Вы также можете использовать диалоговые окна из пользовательского интерфейса jQuery. Обратите внимание, однако, что такие вещи асинхронны, и вам нужно привязать обработчик к событию onclick для каждой кнопки, но это довольно просто реализовать.

Однако я согласен с тем, что отсутствие реального закрытого события ужасно: если вы, например, захотите reset ваше состояние сеанса в back-end только на случай реального закрытия, это проблема.

Ответ 6

Мне нужно было автоматически регистрировать пользователя, когда браузер или вкладка закрываются, но не тогда, когда пользователь переходит к другим ссылкам. Я также не хотел, чтобы подсказка подтверждения показывалась, когда это происходит. После некоторого времени борется с этим, особенно с IE и Edge, вот что я закончил (проверил работу с IE 11, Edge, Chrome и Firefox) после того, как он основывался на подходе this ответить.

Сначала запустите таймер обратного отсчета на сервере в обработчике событий beforeunload в JS. Для работы IE и Edge вызовы ajax должны быть синхронными. Вам также нужно использовать return;, чтобы диалоговое окно подтверждения не отображалось следующим образом:

    window.addEventListener("beforeunload", function (e) {        
      $.ajax({
          type: "POST",
          url: startTimerUrl,
          async: false           
      });
      return;
    });

Запуск таймера устанавливает флаг cancelLogout в значение false. Если пользователь обновляет страницу или переходит к другой внутренней ссылке, флаг cancelLogout на сервере устанавливается в значение true. Как только событие таймера истечет, он проверяет флаг cancelLogout, чтобы узнать, отменено ли событие выхода из системы. Если таймер был отменен, он остановит таймер. Если браузер или вкладка были закрыты, флаг cancelLogout оставался бы ложным, и обработчик события мог бы вывести пользователя из системы.

Замечание по внедрению: я использую ASP.NET MVC 5, и я отменяю logout в переопределенном методе Controller.OnActionExecuted().

Ответ 7

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

Объект sessionStorage хранит данные только для одного сеанса (данные удаляются при закрытии вкладки браузера). (W3Schools)

Это моя ручка.

<div id="Notice">
    <span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
    $("#Notice").click(function() {
     //set sessionStorage on click
        sessionStorage.setItem("dismissNotice", "Hello");
        $("#Notice").remove();
    });
    if (sessionStorage.getItem("dismissNotice"))
    //When sessionStorage is set Do stuff...
        $("#Notice").remove();
</script>

Ответ 8

$(window).unload( function () { alert("Bye now!"); } );

Ответ 9

Нет события, но есть свойство window.closed, которое поддерживается во всех основных браузерах на момент написания этой статьи. Таким образом, если вам действительно нужно знать, что вы можете опросить окно, чтобы проверить это свойство.

if(myWindow.closed){do things}

Примечание: Опрос - это, как правило, не лучшее решение. Событие window.onbeforeunload должно использоваться, если это возможно, единственное предупреждение, которое оно также срабатывает, если вы уходите.

Ответ 10

Попробуйте использовать это:

window.onbeforeunload = function (event) {
    var message = 'Important: Please click on \'Save\' button to leave this page.';
    if (typeof event == 'undefined') {
        event = window.event;
    }
    if (event) {
        event.returnValue = message;
    }
    return message;
};

$(function () {
    $("a").not('#lnkLogOut').click(function () {
        window.onbeforeunload = null;
    });
    $(".btn").click(function () {
        window.onbeforeunload = null;
});
});

Ответ 11

window.onbeforeunload = function() {
  console.log('event');
  return false; //here also can be string, that will be shown to the user
}

Ответ 12

Это можно проверить с помощью window.closed в обработчике событий на этом событии "разгрузить", как это, но требуется время ожидания (поэтому результат не может быть гарантирован, если задержка SMT или закрытие окна):

Пример JSFiddle (проверено на поздних версиях Safari, FF, Chrome, Edge и IE11)

var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write('<html>
   <head><title>CHILD WINDOW/TAB</title></head>
   <body><h2>CHILD WINDOW/TAB</h2></body>
</html>');
win.addEventListener('load',() => {
    document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
    document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
    setTimeout(()=>{
        document.querySelector('.status').innerHTML +=  getChildWindowStatus();
    },1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
    alert(getChildWindowStatus());
}
function getChildWindowStatus() {
  if (win.closed) { 
      return 'Child window has been closed!';
  } else {
      return 'Child window has not been closed!';
  }
}

Ответ 13

Поскольку никто еще не упомянул об этом (8+ лет спустя): WebSocket может быть еще одним эффективным способом обнаружения закрытой вкладки. Пока вкладка открыта и направлена на хост, клиент может поддерживать активное соединение WebSocket с хостом.

Предупреждение: обратите внимание, что это решение действительно жизнеспособно для проекта, только если WebSocket не требует каких-либо дополнительных значительных накладных расходов по сравнению с тем, что вы уже делаете.

В течение разумного периода времени ожидания (например, 2 минуты) серверная сторона может определить, что клиент ушел после отключения WebSocket, и выполнить любое действие, такое как удаление загруженных временных файлов. (В моем крайне специализированном сценарии использования моя цель состояла в том, чтобы прекратить сервер приложений localhost через три секунды после разрыва соединения WebSocket и прекращения всех действий CGI/FastCGI - любые другие поддерживающие соединение не влияют на меня.)

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

Ответ 14

window.onbeforeunload = function ()
{       

    if (isProcess > 0) 
    {
        return true;       
    }   

    else
    { 
        //do something      
    }
}; 

Эта функция отображает диалоговое окно подтверждения, если вы закрываете окно или обновляете страницу во время любого процесса в браузере. Эта функция работает во всех браузерах. Вы должны установить var isProcess в свой процесс ajax.

Ответ 15

window.addEventListener("beforeunload", function (e) {
 var confirmationMessage = "tab close";

 (e || window.event).returnValue = confirmationMessage;     //Gecko + IE
 sendkeylog(confirmationMessage);
 return confirmationMessage;                                //Webkit, Safari, Chrome etc.
}); 

Ответ 16

Я нашел способ, который работает на всех моих браузерах.

Протестировано в следующих версиях: Firefox 57, Internet Explorer 11, Edge 41, один из задержанных Chrome (он не покажет мою версию)

Примечание: onbeforeunload срабатывает, если вы покинете страницу любым способом (обновите, закройте браузер, перенаправите, перейдите, отправьте..). Если вы хотите, чтобы это произошло в браузере, просто привяжите обработчики событий.

  $(document).ready(function(){         

        var validNavigation = false;

        // Attach the event keypress to exclude the F5 refresh (includes normal refresh)
        $(document).bind('keypress', function(e) {
            if (e.keyCode == 116){
                validNavigation = true;
            }
        });

        // Attach the event click for all links in the page
        $("a").bind("click", function() {
            validNavigation = true;
        });

        // Attach the event submit for all forms in the page
        $("form").bind("submit", function() {
          validNavigation = true;
        });

        // Attach the event click for all inputs in the page
        $("input[type=submit]").bind("click", function() {
          validNavigation = true;
        }); 

        window.onbeforeunload = function() {                
            if (!validNavigation) {     
                // ------->  code comes here
            }
        };

  });

Ответ 17

Как отметил @jAndy, нет надлежащего кода javascript для обнаружения закрываемого окна. Я начал с того, что предложил @Syno.

Я прошел мимо такой ситуации, и если вы выполните следующие шаги, вы сможете ее обнаружить.
Я тестировал его на Chrome 67+ и Firefox 61+.

var wrapper = function () { //ignore this

var closing_window = false;
$(window).on('focus', function () {
    closing_window = false; 
   //if the user interacts with the window, then the window is not being 
   //closed
});

$(window).on('blur', function () {

    closing_window = true;
    if (!document.hidden) { //when the window is being minimized
        closing_window = false;
    }
    $(window).on('resize', function (e) { //when the window is being maximized
        closing_window = false;
    });
    $(window).off('resize'); //avoid multiple listening
});

$('html').on('mouseleave', function () {
    closing_window = true; 
    //if the user is leaving html, we have more reasons to believe that he 
    //leaving or thinking about closing the window
});

$('html').on('mouseenter', function () {
    closing_window = false; 
    //if the user mouse its on the page, it means you don't need to logout 
    //them, didn't it?
});

$(document).on('keydown', function (e) {

    if (e.keyCode == 91 || e.keyCode == 18) {
        closing_window = false; //shortcuts for ALT+TAB and Window key
    }

    if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
        closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
    }
});

// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
    closing_window = false;
});

// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
    closing_window = false;

});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
    closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
    closing_window = false;
});

var toDoWhenClosing = function() {

    //write a code here likes a user logout, example: 
    //$.ajax({
    //    url: '/MyController/MyLogOutAction',
    //    async: false,
    //    data: {

    //    },
    //    error: function () {
    //    },
    //    success: function (data) {
    //    },
    //});
};


window.onbeforeunload = function () {
    if (closing_window) {
        toDoWhenClosing();
    }
};

};

Ответ 18

//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
  e = e || window.event;
  var localStorageTime = localStorage.getItem('storagetime')
  if(localStorageTime!=null && localStorageTime!=undefined){
    var currentTime = new Date().getTime(),
        timeDifference = currentTime - localStorageTime;

    if(timeDifference<25){//Browser Closed
       localStorage.removeItem('storagetime');
    }else{//Browser Tab Closed
       localStorage.setItem('storagetime',new Date().getTime());
    }

  }else{
    localStorage.setItem('storagetime',new Date().getTime());
  }
});

JSFiddle Link

Привет всем, я смог добиться кликов "Определить событие браузера и закрытия вкладки", используя локальное хранилище браузера и метку времени. Надеюсь, что все вы решите свои проблемы с помощью этого решения.

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

Я протестировал его в браузере Chrome версии 76.0.3809.132 и обнаружил, что работает

:) Проголосуйте, если вы нашли мой ответ полезным....

Ответ 19

попробуйте это, Я уверен, что это сработает для вас.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
    $(function() {

        try{
            opera.setOverrideHistoryNavigationMode('compatible');
            history.navigationMode = 'compatible';
        }catch(e){}

        function ReturnMessage()
        {
            return "wait";
        }

        function UnBindWindow()
        {
            $(window).unbind('beforeunload', ReturnMessage);
        }

        $(window).bind('beforeunload',ReturnMessage );
    });
</script>

Ответ 20

Попробуйте это. Это будет работать. Метод jquery unload отменяется.

window.onbeforeunload = function(event) {
    event.returnValue = "Write something clever here..";
};

Ответ 21

<script type="text/javascript" language="Javascript">

function DetectBrowserExit()
{
   alert('Execute task which do you want before exit');
}

window.onbeforeunload = function(){ DetectBrowserExit(); }

</script>

Я тестировал этот script в следующих веб-браузерах: В настоящий момент браузер Opera не поддерживает событие onBeforeUnload. Internet Explorer Mozilla Firefox Гугл Хром Safari