Search code examples
javascriptdom-eventsonbeforeunload

How to extract target hostname during onbeforeunload event


I'd like to warn the user when he/she tries to navigate away from my webapp when his/her project is unsaved. Currently I don't care about edit boxes which are currently under edit. I know the project's dirty state from the session.

I quickly realized that if I set a function for the window.onbeforeunload, it'll disturb the user even if he/sh navigates to another page within my webapp. In such case no disturbance needed, the session will be still alive.

I tried a solution derived from Fire onbeforeunload only when window is closed (includes working example)

window.onbeforeunload = function (e) {
    var targetHost = new URL(e.target.URL).hostname;
    if (targetHost != window.location.host)
        return "Project is unsaved!!!";
    else
        return null;
};

The new URL(e.target.URL).hostname results in (at least on IE11):

JavaScript runtime error: Object doesn't support this action

And mysteriously I can't find anything about no new URL(e.target.URL).hostname by any search.

But at the same time I hope this is not impossible, I cannot believe others didn't experience this.


Solution

  • There are two problems in your script:

    window.onbeforeunload = function (e) {
        var targetHost = new URL(e.target.URL).hostname;
        if (targetHost != window.location.host) {
            return "Project is unsaved!!!";
        else
            return null;
    };
    

    The first is that you did not close your if. The second is that e.target.URL is apparently not supported by IE. You need to have an A and a B plan.

    A plan: Applies to the case when e.target.URL exists. In this case, you handle the case as you initially implemented, but with the syntax fix mentioned above.

    B plan: Applies to the case when e.target.URL does not exist. For this case, you should assume that the user leaves the site. You can improve the approach by adding knowledge when the user uses your control to navigate, for instance, you know that a given anchor will stay on the site. In this case, you can define a click event and set a boolean value to true (and the default value of that boolean should be false...), so that later your onbeforeunload event will know that your user stayed on the site even if he or she uses IE.

    So you need a logic like this:

    var targetHost = !!e.target.URL ? (new URL(e.target.URL).hostname) : ((myFlag) ? (window.location.hostname) : ("elsewhere"));