Як захопити подію закриття вікна браузера?


149

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

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

Але це працює і над поданням форми, що не те, що я хочу. Я хочу, щоб подія, яка запускається лише тоді, коли користувач закриє вікно.

Відповіді:


212

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відбудеться це через пару секунд.


8
Так, чудово працює! Новіші версії jquery підтримують $ ('form'). Live ('submit, function () {}).
Венкат Д.

4
Ваше рішення добре, але як я можу скасувати подію у разі оновлення? Я хочу, щоб подія була лише в тому випадку, якщо браузер закритий, жодного випадку оновлення
Refael

Здається, що браузер відображає повернене значення перед завантаженням як діалогове вікно підтвердження. Тому я вважаю, що ця відповідь є більш точною: посилання
tahagh

2
робить це ручка поновлення сторінки з допомогою Ctrl + r, F5, Ctrl + Shift + rі зміна URL браузера?
Арті

1
@Jonny: Зараз це просто .on().
СЛАкс

45

Можливо, просто відв’яжіть beforeunloadобробник подій у обробці події форми submit:

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

3
Чи не так просто не використовувати jQuery, вказавши це у визначенні тегу форми? : `<form onsubmit =" window.onbeforeunload = null; ">
почитав

4
@awe Але вам потрібно буде включити це onsubmit=...до кожної форми. (У мене багато форм на сторінці, у певному веб-сайті)
KajMagnus

16

Для рішення між веб-переглядачами (тестовано в 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


3
Цей працює стабільно у веб-переглядачах. Просто швидка примітка; Я оновив як liveі bindзаяви до on, що чудово працює з останнім рівнем jQuery. Дякую!
Sablefoste


4

Для рішення, яке добре співпрацювало з сторонніми елементами управління, такими як 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;
});

1
Ця відповідь правильна, але для тих, у кого виникли проблеми з цією подією під час оновлення браузера, змініть свій на наступний код: якщо (inFormOrLink! == undefined &&! InFormOrLink)
LeonPierre

4

Моя відповідь спрямована на надання простих орієнтирів.

ЯК

Дивіться відповідь @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?), яке буде чекати, поки відповідь користувача.

Хром : 2 секунди.
Firefox : ∞ (або подвійне клацання, або натискання на закриття)
Edge : ∞ (або подвійне клацання)
Explorer 11 : 0 секунд.
Сафарі : TODO

Що ми використовували для перевірки цього:

  • Сервер Node.js Express з журналом запитів
  • Наступний короткий 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's 2 seconds since requests can take few milliseconds to be sent.

3

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

Просто використання віддачі працювало. Ось мій код

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;
})

1

Можливо, ви могли б обробити OnSubmit і встановити прапор, який ви пізніше перевірте у своєму обробнику OnBeforeUnload.


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

1

На жаль, подія буде спровоковано, перенаправлення нової сторінки чи закриття браузера. Альтернативою є введення ідентифікатора, що викликає подію, і якщо це форма, не запускайте жодної функції, а якщо це не ідентифікатор форми, тоді робіть те, що ви хочете зробити, коли сторінка закривається. Я не впевнений, чи можливо це також безпосередньо і нудно.

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

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


0

Якщо ваше подання форми перенесе їх на іншу сторінку (як я вважаю, це відбувається, отже, і запуск beforeunload), ви можете спробувати змінити подання форми на виклик Ajax. Таким чином, вони не залишать вашу сторінку, коли вони надсилають форму, і ви можете використовувати свій beforeunloadприв'язуючий код за своїм бажанням.


0

Мій випуск: Подія "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');   
}

0

Станом на jQuery 1.7 метод .live () застарілий. Використовуйте .on (), щоб приєднати обробники подій. Користувачі старих версій jQuery повинні використовувати .delegate () у перевазі .live ()

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

на повне або посилання

$(window).unbind();

0

Спробуйте і це

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
    }
};

-1

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

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");
    }
  }
}

Це не працює. У момент запуску події вивантаження (btw, вона запускається з документа), window.closed === false;
Сергій П. aka azure

-1
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`

-7

Слідом працював для мене;

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

це функція jquery.
maxisam

7
event.clientYНегативна , якщо натиснути на кнопку Закрити Браузер кнопку закриття або вкладки. Однак це значення є позитивним, коли ви перезавантажуєте сторінку за допомогою комбінацій клавіш (F5, Ctrl-R) або закриваєте браузер за допомогою скорочень клавіатури (наприклад, Alt-F4). Таким чином, ви не можете покластися на положення події, щоб відрізняти подію закриття браузера від події перезавантаження сторінки.
Жульєн Кронегг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.