Как захватить событие закрытия окна браузера?

Я хочу захватить событие закрытия окна браузера/вкладки. Я попробовал следующее с jQuery:

jQuery(window).bind(
    "beforeunload", 
    function() { 
        return confirm("Do you really want to close?") 
    }
)

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

Ответ 1

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

Например, он будет запущен, если пользователь отправит форму, щелкнет ссылку, закроет окно (или вкладку) или перейдет на новую страницу с помощью адресной строки, окна поиска или закладки.

Вы можете исключить формы и гиперссылки (кроме других фреймов) со следующим кодом:

var inFormOrLink;
$('a').on('click', function() { inFormOrLink = true; });
$('form').on('submit', function() { inFormOrLink = true; });

$(window).on("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

Для версий jQuery старше 1.7 попробуйте следующее:

var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

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

Обратите внимание, что если другой обработчик событий отменяет отправку или навигация, вы потеряете приглашение подтверждения, если окно фактически закрыто позже. Вы можете исправить это, записав время в событиях submit и click и проверив, будет ли beforeunload более чем на пару секунд позже.

Ответ 2

Возможно, просто отвяжите обработчик события beforeunload в обработчике формы submit:

jQuery('form').submit(function() {
    jQuery(window).unbind("beforeunload");
    ...
});

Ответ 3

Для кросс-браузерного решения (протестированного в Chrome 21, IE9, FF15) рассмотрите следующий код, который представляет собой слегка измененную версию кода Slaks:

var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind('beforeunload', function(eventObject) {
    var returnValue = undefined;
    if (! inFormOrLink) {
        returnValue = "Do you really want to close?";
    }
    eventObject.returnValue = returnValue;
    return returnValue;
}); 

Обратите внимание, что с Firefox 4 появилось сообщение "Вы действительно хотите закрыть?" не отображается. FF просто отображает общее сообщение. См. Примечание в https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload

Ответ 4

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

Ответ 5

Для решения, которое хорошо работало с сторонними элементами управления, такими как Telerik (например, RadComboBox) и DevExpress, которые используют теги Anchor по разным причинам, рассмотрите следующий код, который представляет собой слегка улучшенную версию кода desm с лучшим селектор для тегов привязки для самостоятельного таргетинга:

var inFormOrLink;
$('a[href]:not([target]), a[href][target=_self]').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind('beforeunload', function(eventObject) {
    var returnValue = undefined;
    if (! inFormOrLink) {
        returnValue = "Do you really want to close?";
    }
    eventObject.returnValue = returnValue;
    return returnValue;
});

Ответ 6

Я использовал Slaks, но это не работает, как есть, поскольку onbeforeunload returnValue анализируется как строка, а затем отображается в окне подтверждения браузера. Так отображается значение true, например "true".

Просто используйте return. Вот мой код

var preventUnloadPrompt;
var messageBeforeUnload = "my message here - Are you sure you want to leave this page?";
//var redirectAfterPrompt = "http://www.google.co.in";
$('a').live('click', function() { preventUnloadPrompt = true; });
$('form').live('submit', function() { preventUnloadPrompt = true; });
$(window).bind("beforeunload", function(e) { 
    var rval;
    if(preventUnloadPrompt) {
        return;
    } else {
        //location.replace(redirectAfterPrompt);
        return messageBeforeUnload;
    }
    return rval;
})

Ответ 7

Возможно, вы могли бы обработать OnSubmit и установить флаг, который вы позже проверите в своем обработчике OnBeforeUnload.

Ответ 8

jQuery(window).bind(
                    "beforeunload",
                      function (e) {
                          var activeElementTagName = e.target.activeElement.tagName;
                          if (activeElementTagName != "A" && activeElementTagName != "INPUT") {
                              return "Do you really want to close?";
                          }
                      })

Ответ 9

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

Вы можете сделать некоторые мелочи, прежде чем клиент закроет вкладку. javascript обнаружить браузер закрыть вкладку/закрыть браузер, но если ваш список действий большой, а вкладка закрывается до того, как она будет завершена, вы беспомощны. Вы можете попробовать, но с моим опытом donot зависит от него.

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";
  /* Do you small action code here */
  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage;                            //Webkit, Safari, Chrome
});

https://developer.mozilla.org/en-US/docs/Web/Reference/Events/beforeunload?redirectlocale=en-US&redirectslug=DOM/Mozilla_event_reference/beforeunload

Ответ 10

Мой ответ направлен на предоставление простых тестов.

КАК

См. ответ @SLaks.

$(window).on("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

Сколько времени займет браузер, чтобы, наконец, закрыть страницу?

Когда пользователь закрывает страницу (x или CTRL + W), браузер выполняет данный код beforeunload, но не на неопределенный срок. Единственным исключением является окно подтверждения (return 'Do you really want to close?), которое будет ждать ответа пользователя.

Chrome: 2 секунды.
Firefox: ∞ (или двойной щелчок или принудительное закрытие)
Edge: ∞ (или двойной щелчок)
Проводник 11: 0 секунд.
Safari: TODO

Что мы использовали для проверки этого:

  • A Node.js Экспресс-сервер с журналом запросов
  • Следующий короткий HTML файл

Что он делает, так это отправить как можно больше запросов, прежде чем браузер завершит свою страницу (синхронно).

<html>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>
    function request() {
        return $.ajax({
            type: "GET",
            url: "http://localhost:3030/" + Date.now(),
            async: true
        }).responseText;
    }
    window.onbeforeunload = () => {
        while (true) {
            request();
        }
        return null;
    }
    </script>
</body>
</html>

Выход Chrome:

GET /1480451321041 404 0.389 ms - 32  
GET /1480451321052 404 0.219 ms - 32  
...  
GET /hello/1480451322998 404 0.328 ms - 32

1957ms ≈ 2 seconds // we assume it 2 seconds since requests can take few milliseconds to be sent.

Ответ 11

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

Ответ 12

My Issue: событие onbeforeunload будет срабатывать только в том случае, если было нечетное количество отправлений (кликов). У меня было сочетание решений из подобных потоков в SO, чтобы мое решение работало. хорошо, мой код будет говорить.

<!--The definition of event and initializing the trigger flag--->


$(document).ready(function() {
updatefgallowPrompt(true);
window.onbeforeunload = WarnUser;   
}

function WarnUser() {
var allowPrompt = getfgallowPrompt();
    if(allowPrompt) {
    saveIndexedDataAlert();
    return null;
    } else {
        updatefgallowPrompt(true);
        event.stopPropagation
    }
}

<!--The method responsible for deciding weather the unload event is triggered from submit or not--->
function saveIndexedDataAlert() {
    var allowPrompt = getfgallowPrompt();
    var lenIndexedDocs = parseInt($('#sortable3 > li').size()) + parseInt($('#sortable3 > ul').size());

    if(allowPrompt && $.trim(lenIndexedDocs) > 0) {
        event.returnValue = "Your message";
    } else {
        event.returnValue = "   ";
        updatefgallowPrompt(true);
    }
}

<!---Function responsible to reset the trigger flag---->
$(document).click(function(event) {  
$('a').live('click', function() { updatefgallowPrompt(false); });
 });

<!--getter and setter for the flag---->
function updatefgallowPrompt (allowPrompt){ //exit msg dfds
    $('body').data('allowPrompt', allowPrompt); 
}   

function getfgallowPrompt(){        
    return $('body').data('allowPrompt');   
}

Ответ 13

Как и в jQuery 1.7, метод .live() устарел. Используйте .on() для присоединения обработчиков событий. Пользователи более старых версий jQuery должны использовать .delegate() в предпочтении .live()

$(window).bind("beforeunload", function() {
    return true || confirm("Do you really want to close?"); 
}); 

по завершении или ссылку

$(window).unbind();

Ответ 14

Попробуйте также

window.onbeforeunload = function ()
{       
    if (pasteEditorChange) {
        var btn = confirm('Do You Want to Save the Changess?');
           if(btn === true ){
               SavetoEdit();//your function call
           }
           else{
                windowClose();//your function call
           }
    }  else { 
        windowClose();//your function call
    }
};

Ответ 15

Просто проверьте...

function wopen_close(){
  var w = window.open($url, '_blank', 'width=600, height=400, scrollbars=no, status=no, resizable=no, screenx=0, screeny=0');
  w.onunload = function(){
    if (window.closed) {
       alert("window closed");
    }else{ 
       alert("just refreshed");
    }
  }
}

Ответ 16

var validNavigation = false;
            jQuery(document).ready(function () {

                wireUpEvents();
            });

            function endSession() {
                // Browser or broswer tab is closed
                // Do sth here ...
                alert("bye");
            }

            function wireUpEvents() {
                /*
                * For a list of events that triggers onbeforeunload on IE
                * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
                */
                window.onbeforeunload = function () {
                    debugger
                    if (!validNavigation) {
                        endSession();
                    }
                }

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

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

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

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

            }`enter code here`

Ответ 17

После меня работали,

 $(window).unload(function(event) {
    if(event.clientY < 0) {
        //do whatever you want when closing the window..
    }
 });