Multiple OnBeforeUnload

Try this:

var f = window.onbeforeunload;
window.onbeforeunload = function () {
    f();
    /* New code or functions */
}

You can modify this function many times , without losing other functions.


My idea:

var callbacks = [];
window.onbeforeunload = function() {
    while (callbacks.length) {
        var cb = callbacks.shift();
        typeof(cb)==="function" && cb();
    }
}

and

callbacks.push(function() {
    console.log("callback");
});

I felt this has not been answered completely, because no examples were shown using addEventListener (but The MAZZTer pointed out the addEventListener solution though). My solution is the same as Julian D. but without using jQuery, only native javascript.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Before Unload</title>
</head>
<body>
    <p>Test</p>

    <script>
      window.addEventListener('beforeunload', function (event) {
        console.log('handler 1')
        event.preventDefault()
        event.returnValue = ''
      });

      window.addEventListener('beforeunload', function (event) {
        console.log('handler 2')
      });
    </script>
</body>
</html>

In this example, both listeners will be executed. If any other beforeunload listeners were set, it would not override them. We would get the following output (order is not guaranteed):

handler 1
handler 2

And, importantly, if one or more of the event listener does event.preventDefault(); event.returnValue = '', a prompt asking the user if he really wants to reload will occur.

This can be useful if you are editing a form and at the same time you are downloading a file via ajax and do not want to lose data on any of these action. Each of these could have a listener to prevent page reload.

const editingForm = function (event) {
  console.log('I am preventing losing form data')
  event.preventDefault()
  event.returnValue = ''
}

const preventDownload = function (event) {
  console.log('I am preventing a download')
  event.preventDefault()
  event.returnValue = ''
}

// Add listener when the download starts
window.addEventListener('beforeunload', preventDownload);
// Add listener when the form is being edited
window.addEventListener('beforeunload', editingForm);

// Remove listener when the download ends
window.removeEventListener('beforeunload', preventDownload);
// Remove listener when the form editing ends
window.removeEventListener('beforeunload', editingForm);

You only need to take care of this if you are not using event observing but attach your onbeforeunload handler directly (which you should not). If so, use something like this to avoid overwriting of existing handlers.

(function() {
    var existingHandler = window.onbeforeunload;
    window.onbeforeunload = function(event) {
        if (existingHandler) existingHandler(event);

        // your own handler code here
    }
})();

Unfortunately, you can't prevent other (later) scripts to overwrite your handler. But again, this can be solved by adding an event listener instead:

$(window).unload(function(event) {
    // your handler code here
});