6

I have window.onbeforeunload triggering properly. It's displaying a confirmation box to ensure the user knows they are navigating (closing) the window and that any unsaved work will be erased.

I have a unique situation where I don't want this to trigger if a user navigates away from the page by clicking a link, but I can't figure out how to detect if a link has been clicked inside the function to halt the function. This is what I have for code:

window.onbeforeunload = function() { var message = 'You are leaving the page.'; /* If this is Firefox */ if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) { if(confirm(message)) { history.go(); } else { window.setTimeout(function() { window.stop(); }, 1); } } /* Everything else */ else { return message; } } 

3 Answers 3

7

You're looking for deferred event handling. I'll explain using jQuery, as it is less code:

window._link_was_clicked = false; window.onbeforeunload = function(event) { if (window._link_was_clicked) { return; // abort beforeunload } // your event handling }; jQuery(document).on('click', 'a', function(event) { window._link_was_clicked = true; }); 

a (very) poor man's implementation without jQuery's convenient delegation handling could look like:

document.addEventListener("click", function(event) { if (this.nodeName.toLowerCase() === 'a') { window._link_was_clicked = true; } }, true); 

this allows all links on your page to leave without invoking the beforeunload handler. I'm sure you can figure out how to customize this, should you only want to allow this for a specific set of links (your question wasn't particularly clear on that).

Sign up to request clarification or add additional context in comments.

4 Comments

This is great thanks for the reply. I'm trying to use this without jQuery - and I'm trying to figure out how to integrate the poormans implementation but can't seem to figure it out (forgive me, I'm a bit of a JS newb).
Your code was semi-right. I've answered the question with the full answer.
If anyone have problem making it work in IE I had to return undefined instead of null. Works in both ie and chrome.
Re your second code block: this in that handler will always refer to document, which obviously will never be an a element. In 2013, you needed a loop starting in event.target and stopping at this and checking each element in-between. Here in 2018, on really up-to-date modern browsers, you can use the DOM's new closest function (which is very like jQuery's): if (event.target.closest("a"))...
6
var link_was_clicked = false; document.addEventListener("click", function(e) { if (e.target.nodeName.toLowerCase() === 'a') { link_was_clicked = true; } }, true); window.onbeforeunload = function() { if(link_was_clicked) { link_was_clicked = false; return; } //other code here } 

Comments

1

You can differ between a link unload or a reload/user entering a different address unload s by using a timer. This way you know the beforeunload was triggered directly after the link click.

Example using jQuery:

$('a').on('click', function(){ window.last_clicked_time = new Date().getTime(); window.last_clicked = $(this); }); $(window).bind('beforeunload', function() { var time_now = new Date().getTime(); var link_clicked = window.last_clicked != undefined; var within_click_offset = (time_now - window.last_clicked_time) < 100; if (link_clicked && within_click_offset) { return 'You clicked a link to '+window.last_clicked[0].href+'!'; } else { return 'You are leaving or reloading the page!'; } }); 

(tested in Chrome)

1 Comment

IE, Edge, Firefox ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.