How to detect browser back button events - cross browser
P粉141911244
2023-08-23 16:23:49
<p>How to explicitly detect if the user pressed the back button in the browser? </p>
<p>How do I use the <code>#URL</code> system to force the use of an in-page back button in a single-page web application? </p>
<p>Why doesn’t the browser back button trigger its own event? ? </p>
You can try
popstate
event handler, for example:Note: For best results, you should only load this code on the specific page where you want to implement the logic to avoid any other unexpected issues.
The popstate event is fired every time the current history entry changes (the user navigates to a new state). When the user clicks the browser's back/forward button or when
history.back()
,history.forward()
,history.go()
, This happens when the > method is called programmatically.event.state
is an attribute of the event, equal to the historical state object.For jQuery syntax, wrap it (add an even listener after the document is ready):
See also: window.onpopstate on page load
See also Sample pages on Single Page Applications and HTML5 PushState:
This should be compatible with Chrome 5, Firefox 4, IE 10, Safari 6, Opera 11.5 and similar versions.
(Note: Based on Sharky's feedback, I added code to detect the backspace key)
So, I see these questions on SO a lot, and have recently run into issues controlling the back button functionality myself. After days of searching for the best solution for my application (single page with hashed navigation), I came up with a simple, cross-browser, library-free system to detect the back button.
Most people recommend using:
However, this function is also called when the user uses an in-page element that changes the position hash. This is not the best user experience when the user clicks and the page moves back or forward.
To give you a general outline of my system, as the user moves through the interface, I will populate an array with the previous hash values. It looks like this:
very simple. I do this to ensure cross-browser support as well as support for older browsers. Just pass the new hash value to the function and it will store it for you, then change the hash value (and then put it in the browser's history).
I also took advantage of an in-page back button that uses a
lasthash
array to move the user between pages. It looks like this:So this moves the user back to the last hash and removes the last hash from the array (I don't have a forward button now).
so. How do I detect if the user used my in-page back button or browser button?
At first I looked at
window.onbeforeunload
but to no avail - it is only called when the user wants to change the page. This does not happen in a single page application using hash navigation.So, after some more digging, I saw the suggestion to try setting a flag variable. In my case, the problem was that I would try to set it, but since everything is asynchronous, it wouldn't always be set in time for the if statement in the hash change.
.onMouseDown
is not always called in click , and adding it to onclick will never trigger it quickly enough.That's when I started researching the difference between
documents
andwindows
. My final solution was to set the flag usingdocument.onmouseover
and disable it usingdocument.onmouseleave
.What happens is that when the user's mouse is within the document area (read: the rendered page, but not the browser frame), my boolean is set to
true
. Once the mouse leaves the document area, the boolean value flips tofalse
.In this way, I can change
window.onhashchange
to:You will notice the check for
#undefined
. This is because if there is no history available in my array it returnsundefined
. I use this to ask the user if they want to leave using thewindow.onbeforeunload
event.So, in a nutshell, for anyone who doesn't necessarily use an in-page back button or an array to store history:
This is what you want. A simple three-part approach to detecting back button usage versus in-page elements in terms of hash navigation.
edit:
To ensure that the user does not use the backspace key to trigger the back event, you can also include the following (thanks for this question):