Remove fragment in URL with JavaScript w/out causing page reload
Asked Answered
B

8

47

Background: I have an HTML page which lets you expand certain content. As only small portions of the page need to be loaded for such an expansion, it's done via JavaScript, and not by directing to a new URL/ HTML page. However, as a bonus the user is able to permalink to such expanded sections, i.e. send someone else a URL like

http://example.com/#foobar

and have the "foobar" category be opened immediately for that other user. This works using parent.location.hash = 'foobar', so that part is fine.

Now the question: When the user closes such a category on the page, I want to empty the URL fragment again, i.e. turn http://example.com/#foobar into http://example.com/ to update the permalink display. However, doing so using parent.location.hash = '' causes a reload of the whole page (in Firefox 3, for instance), which I'd like to avoid. Using window.location.href = '/#' won't trigger a page reload, but leaves the somewhat unpretty-looking "#" sign in the URL. So is there a way in popular browsers to JavaScript-remove a URL anchor including the "#" sign without triggering a page refresh?

Benniebenning answered 6/11, 2008 at 15:14 Comment(2)
This related question is an interesting read.Chancellorship
Does this answer your question? How to remove the hash from window.location (URL) with JavaScript without page refresh?Chivaree
M
59

As others have mentioned, replaceState in HTML5 can be used to remove the URL fragment.

Here is an example:

// remove fragment as much as it can go without adding an entry in browser history:
window.location.replace("#");

// slice off the remaining '#' in HTML5:    
if (typeof window.history.replaceState == 'function') {
  history.replaceState({}, '', window.location.href.slice(0, -1));
}
Middleoftheroad answered 11/12, 2012 at 16:20 Comment(3)
Solid. I appreciate the detection of ability to remove the #, but backwards compatible.Amigo
on spot answer. I am using this nowAshleyashli
history.replaceState is great, but the slice is fragile. Have a look at the Location interface for alternatives.Sitka
R
14

Since you are controlling the action on the hash value, why not just use a token that means "nothing", like "#_" or "#default".

Rossner answered 6/11, 2008 at 15:22 Comment(3)
I think this is an idea worthy of consideration.Stilted
Yes, you can also use a blank anchor, so then the URL ends up as being example.com/#. This is almost perfect, but I think it can also end up looking slightly confusing to some visitors. Ideally there whouldn't even be that hash character showing...Benniebenning
Obviously. Your scripts should function with nothing in the hash.Ashurbanipal
K
4

You could use the shiny new HTML5 window.history.pushState and replaceState methods, as described in ASCIIcasts 246: AJAX History State and on the GitHub blog. This lets you change the entire path (within the same origin host) not just the fragment. To try out this feature, browse around a GitHub repository with a recent browser.

Karelian answered 6/1, 2011 at 19:44 Comment(0)
H
2

Put this code on head section.

<script type="text/javascript">
    var uri = window.location.toString();
    if (uri.indexOf("?") > 0) {
        var clean_uri = uri.substring(0, uri.indexOf("?"));
        window.history.replaceState({}, document.title, clean_uri);
    }
</script>
Harijan answered 7/1, 2016 at 16:52 Comment(0)
S
1

There is also another option instead of using hash, you could use javascript: void(0); Example: <a href="javascript:void(0);" class="open_div">Open Div</a>

I guess it also depends on when you need that kind of link, so you better check the following links:

How to use it: http://www.brightcherry.co.uk/scribbles/2010/04/25/javascript-how-to-remove-the-trailing-hash-in-a-url/ or check debate on what is better here: Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?

Selfrevealing answered 5/1, 2011 at 9:29 Comment(0)
W
-1
$(document).ready(function() {
        $(".lnk").click(function(e) {
            e.preventDefault();
            $(this).attr("href", "stripped_url_via_desired_regex");
        });
    });
Whidah answered 6/11, 2008 at 15:28 Comment(1)
Thank you Florin, could you please explain what this code does?Benniebenning
C
-1

So use

parent.location.hash = '' first

then do

window.location.href=window.location.href.slice(0, -1);
Clypeate answered 16/7, 2009 at 16:58 Comment(2)
changing location.href in any way will reload the page.Ring
That does work to get rid of the entire fragment including the '#' but Evgeny is right, it reloads the pageAmrita
C
-2

As others have said, you can't do it. Plus... seriously, as the jQuery Ajaxy author - I've deployed complete ajax websites for years now - and I can guarantee no end user has ever complained or perhaps ever even noticed that there is this hash thing going on, user's don't care as long as it works and their getting what they came for.

A proper solution though is HTML5 PushState/ReplaceState/PopState ;-) Which doesn't need the fragement-identifier anymore: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history For a HTML5 and HTML4 compatible project that supports this HTML5 State Functionality check out https://github.com/browserstate/History.js :-)

Cranium answered 5/1, 2011 at 9:58 Comment(1)
There are better reasons to do that than "the user cares". For example: wistia.com/blog/fresh-urlHiginbotham

© 2022 - 2024 — McMap. All rights reserved.