Question
Given navigation from /page.html#A
to /page.html#B
, is there a way to distinguish between a user:
- Clicking the browsers's 'back' button, and
- Manually changing the url back to
/page.html#A
?
Background / Context
I'm building a web app, where a single page transitions between multiple slides of content, each identified by a specific location hash, eg '#A'
, '#B'
.
For example, when the user is on slide 'A', and selects option 'B', the location changes from /page.html#A
to /page.html#B
.
After the transition, location.hash==#B
, and back()
(either via JS or browser button) would return the user to location.hash==#A
.
However, there is nothing to prevent a user from manually changing the hash in the URL bar. In this case the browser would consider this a navigation forward, inserting /page.html#B
in the back history. That is, navigation history would be #A
> #B
> #A
and clicking back would now take a user to #B
.
I need to distinguish between these two cases so that when I know the user has manually updated the url hash, I can trigger go(N)
to synchronise the browser back/next state.
Attempts so far
1) HTML5 popstate
event:
I had hoped that the html5 popstate event ( https://developer.mozilla.org/en-US/docs/Web/Events/popstate ) would only be fired for case#1, but I can confirm it fires in both cases.
2) Browser .onhashchange
event
I can confirm that if present, the event is fired in both cases
3) jQuery mobile hashChange()
I can confirm is fired in both cases
4) Read browser navigation history
My next thought would be to maintain a JS array of hash history, and compare whether the new hash and browser history match the JS array, but JS can't read the browser location history for security reasons.
Thoughts
I know that if I call window.history.forward(), and no page exists, nothing happens. I'm thinking a JS array of hash history, calling forward(), checking the new location.hash (as security now allows it), comparing to JS array, then calling go(N) to synchronise the browser back/next state. But it's a bit messy.