Trigger an event when user navigates away

2020-05-30 02:03发布

I need to call a JavaScript/jQuery function which has a few lines of code in it, on a PHP page when the user closes his window/tab or navigates away by clicking a link. I've tried the onbeforeunload function but only the return "blah blah blah;" part executes and everything else is ignored. I've also tried the .unload method from jQuery but for some reason this code doesn't run.

$(window).unload(function() {
    alert('blah blah blah');
});

Please suggest alternatives. Thanks..

3条回答
对你真心纯属浪费
2楼-- · 2020-05-30 02:17

This is an old question, but I wanted to share an alternative approach that has the benefit of working with high consistency:

Establish a WebSocket connection to the server, and when the client navigates away the WebSocket connection will be closed. Server-side, you can detect the closed connection in a callback and run whatever code you need on the server.

Executing Javascript on page unload is often unreliable (as discussed in the other answer) because it's inherently at odds with the user's intention. This method will always work, although it is admittedly quite a bit more cumbersome to implement.

This does change the context of your "run before leaving" code from client-side to server-side, but I imagine for most cases the difference is inconsequential. Anything you want to run client-side before the client leaves your page is probably not going to change anything the client sees, so it's probably fine to run it server side. If there is specific data you need from the client you can send it through the WebSocket to the server.

The only situation I can think of off the top of my head where this might cause unexpected behavior is if the user loses the WS connection without actually navigating away, e.g. they lose internet or put their computer to sleep. Whether or not that's a big deal is probably highly dependent on what kind of code you're trying to execute.

查看更多
老娘就宠你
3楼-- · 2020-05-30 02:31

Here is a simple working example. Whatever you return from the unload callback will be displayed in a browser popup confirmation.

Working example sending Ajax request before unload http://jsfiddle.net/alexflav23/hujQs/7/

The easiest way to do this:

window.onbeforeunload = function(event) {
    // do stuff here
    return "you have unsaved changes. Are you sure you want to navigate away?";
};

in jQuery:

$(window).on("beforeunload", function() {
    $.ajax("someURL", {
        async: false,
        data: "test",
        success: function(event) {
             console.log("Ajax request executed");
        }
    });
    return "This is a jQuery version";
});

Look into the Network tab of the browser. You will see how the request is being sent as you wanted to do. Just send the appropriate data.

Bear in mind all operations triggered must be synchronous, so you can only make synchronous ajax requests for instance. However, the above is not entirely reliable for any purpose.

Opt for periodic back-up of user data to localStorage and sync with the server automatically . Keep window.onbeforeunload just as an extra precaution, but not as a main mechanism. It's well known to cause problems.

查看更多
放荡不羁爱自由
4楼-- · 2020-05-30 02:33

In many projects of mine, the mentioned methods here are instable. The only thing that works for me is to bind the event as original attribute on the body element.

<body onunload="my_function_unload()">

jQuery method:

$('body').attr('onunload', 'my_function_unload()');

From an iframe:

<body onunload="window.parent.my_function_unload()">

jQuery method:

$('<iframe />').load(function(){
    $body = $(this).contents().find('body');
    $body.attr('onunload', 'window.parent.my_function_unload()');
}

Also, important, no arguments in the attribute, and the function must be in the global window scope, otherwise nothing happens.

For example, common mistake If your my_function_unload() are wrapped inside a ;( function( $ ) {... OR $(document).ready(function(){... AS my_function_unload() must be outside that private scope. And dont forget to use jQuery instead of $ prefix then. (Working with Wordpress for example)

查看更多
登录 后发表回答