How to make the browser back button disregard hash tags?

こ雲淡風輕ζ 提交于 2019-12-04 19:29:35

问题


I have a website that uses hashes to open/close some tabs and layers on the current page. The reason behind using hashes is, that if a user visits another page via a link and then goes back to the original page all tabs and layers should open up exactly as they were when leaving that page.

The problem is, that while being on the first page and using the browser back button, only the hashes change and the user must click multiple times to actually go back to the last 'real' page.


Can that behaviour be changed? Here's an example workflow:

So I am visiting a page:

start.php > click link > processing.php > click tab, hash changes >

processing.php#1 > click a different section on the page, hash changes to >

processing.php#1-2

Now when I hit the browser back button I want to go back to:

start.php NOT processing.php#1


BUT! When I go from:

processing.php#1-2 > navigate to > otherpage.php

and then hit the back button from there, I need to go back to:

processing.php#1-2

in order to restore the open tabs and layers.

Is that possible!? Any help is appreciated!


回答1:


As far as I know, you can’t solve this without JavaScript. The fragment is part of the URL, and when it changes, the new URL is added to history.

I would suggest using location.replace() when you want to change the URL without creating a history entry. Instead of setting window.location.hash, try this:

window.location.replace('#1');

I’ll leave it up to you to pick the best way to integrate this into your website, but here’s one minimally-tested option for catching clicks on links:

$(window).on('click', 'a', function(e){
    var href = $(e.target).attr('href');
    if (href && href[0] === '#') {
        window.location.replace(e.target.href);
        return false;
    }
});



回答2:


That's intentional browser behavior, and is the proper use of hash tags. As a result, I suggest considering whether the javascript that is using those hash tags is the problem, and to change it to a different storage method. Effectively, you can just use a globally available javascript variable for that purpose, because no page reload will be happening so the variable will persist.

window.stage = 'start';

// Another stage
window.stage = 'onfire'

You'll still want to suppress the standard behavior from clicks for js elements, of course.

Alternatively, if you want the stages to be stored, but not "navigatable", you can consider using localstorage on more modern browsers.

EDIT: (based on the new information)

The thing that you are trying to do is an extremely common scenario in webdev because pages don't save much by way of their user's state/information.

You want to store information about what your users have completed, what stage they are at in a process. Even when they have navigated away from a page.

There are somewhat limited number of places to "store" data: the hash, localStorage, cookies, or client-side, and that's about it. If I were a user of your page, I suspect that I would want my data stored regardless -how- I navigate through your app.

So I suggest considering a better location for storing the state of your webpage than the hash, which is generally designed for navigation. If they're going to be logged in via php, just store it via php to the database. If not, then store it to localStorage where available and fallback to cookies, or just use cookies.

Your end navigation may look as tangled as this: start page > processing page > any other page > processing page > leave the site > return to processing page

But each time they return to the processing page, their data will be there stored, in the state that they left it.

If you must use a hash for some reason, @Sidnicious's answer has a way that may skip the step of creating a history entry, so if you use that for all the stages except the one before you change pages, your history will look like this: start>processing.php>processing.php#final>otherpage.php which may cut down the back button hits down to an acceptable level.




回答3:


I've encountered with the same issue as the one you described. I agree with Ivan Ivković's idea. The following is my code and it works for my case. I'm new to JS, but hope it helps.

var counter = 0;
window.onhashchange = function() {
    window.history.replaceState({visited: ++counter}, "visited page", 

window.location.search+window.location.hash);
}

window.onpopstate = function(event) {
    if(event.state.visited && counter>event.state.visited) {
    counter -= 2;
    window.history.go(-1*event.state.visited);
    }
    else {
    counter = event.state.visited;
    }
}



回答4:


Maybe prevent the default behavior and make the jump to the hash with javascript?

$("a").click(function(event) {
  $("html,body").scrollTop($(this.hash)[0].offsetTop)
  event.preventDefault();
});



回答5:


You can count how many hashes you've clicked since you've loaded the page, then use that count with history.go( - countHashes) to go back to your page.



来源:https://stackoverflow.com/questions/8747714/how-to-make-the-browser-back-button-disregard-hash-tags

工具导航Map