56

I have the following code:

$('ul.questions li a').click(function(event) {
    $('.tab').hide();
    $($(this).attr('href')).fadeIn('slow');
    event.preventDefault();
    window.location.hash = $(this).attr('href');
});

This simply fades a div in based on when you click but I want the page URL hash tag to change when you click so people can copy and bookmark it. At the moment this effectively reloads the page when the hash tag is change.

Is it possible to change the hash tag and not reload the page to prevent the jumping effect?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
daveredfern
  • 1,235
  • 4
  • 14
  • 15
  • 1
    I ran the following on this current page, and it did exactly what you want (no page reload): $("a").click(function(event){event.preventDefault();window.location.hash = $(this).attr('href');}). Maybe at the point where your code runs, the page isn't loaded yet? Check how many items are in `$('ul.questions li a')` – Rob Fonseca-Ensor Dec 21 '09 at 09:49

5 Answers5

84

This works for me

$('ul.questions li a').click(function(event) {
    event.preventDefault();
    $('.tab').hide();
    window.location.hash = this.hash;
    $($(this).attr('href')).fadeIn('slow');
});

Check here http://jsbin.com/edicu for a demo with almost identical code

jitter
  • 53,475
  • 11
  • 111
  • 124
  • Hello, Yes it does work but when the page is scrolling it jumps to the div when the hash link is changed. – daveredfern Dec 21 '09 at 11:50
  • Check changed code which fixes that. If you don't want that to happen you just have to switch the last two lines. The original order was yours and I kept it that way because I thought that's what you wanted – jitter Dec 21 '09 at 12:05
4

You could try catching the onload event. And stopping the propagation dependent on some flag.

var changeHash = false;

$('ul.questions li a').click(function(event) {
    var $this = $(this)
    $('.tab').hide();  //you can improve the speed of this selector.
    $($this.attr('href')).fadeIn('slow');
    StopEvent(event);  //notice I've changed this
    changeHash = true;
    window.location.hash = $this.attr('href');
});

$(window).onload(function(event){
    if (changeHash){
        changeHash = false;
        StopEvent(event);
    }
}

function StopEvent(event){
    event.preventDefault();
    event.stopPropagation();
    if ($.browser.msie) {
        event.originalEvent.keyCode = 0;
        event.originalEvent.cancelBubble = true;
        event.originalEvent.returnValue = false;
    }
}

Not tested, so can't say if it would work

James Wiseman
  • 29,946
  • 17
  • 95
  • 158
2

The accepted answer didn't work for me as my page jumped slightly on click, messing up my scroll animation.

I decided to update the entire URL using window.history.replaceState rather than using the window.location.hash method. Thus circumventing the hashChange event fired by the browser.

// Only fire when URL has anchor
$('a[href*="#"]:not([href="#"])').on('click', function(event) {

    // Prevent default anchor handling (which causes the page-jumping)
    event.preventDefault();

    if ( location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname ) {
        var target = $(this.hash);
        target = target.length ? target : $('[name=' + this.hash.slice(1) +']');

        if ( target.length ) {    
            // Smooth scrolling to anchor
            $('html, body').animate({
                scrollTop: target.offset().top
            }, 1000);

            // Update URL
            window.history.replaceState("", document.title, window.location.href.replace(location.hash, "") + this.hash);
        }
    }
});
Swen
  • 767
  • 1
  • 9
  • 31
2

You can set your hash directly to URL too.

window.location.hash = "YourHash";

The result : http://url#YourHash

0

You can simply assign it a new value as follows,

window.location.hash
Shahrukh Anwar
  • 2,544
  • 1
  • 24
  • 24