2

I am using bootstrap's scrollspy to change the navbar item highlighting on page scroll, and then using history.replaceState to add the hash to the url. This question gave me the idea for that part. I also use some jquery to implement a 'smooth scroll' when a navigation item is clicked and I turn the scrollspy off while 'smooth scrolling' down to the anchor, then add the hash to the url and turn scrollspy back on.

The scrollspy part is working fine, the problem comes when clicking on a navigation link. It works as expected in Chrome and Firefox, but in IE 10 & 11 it adds undefined before the hash in the url when clicking on a link and I can't work out why.

Here's my script:

//initiate scroll spy
$('body').scrollspy({ target: '.spy-active', offset: $offset + 1 });
$('.spy-active').on('activate.bs.scrollspy', function (e) {
    if (history.replaceState) {
    history.replaceState(null, "", $('a[href*=#]:not([href=#])', e.target).attr("href"));
    }
});

//smooth scroll
$('a[href*=#]:not([href=#])').click(function (e) {
    e.preventDefault();
    //deactivate scrollspy for duration of transition
    $('nav').removeClass('spy-active');

    //remove active class from all list items
    $('li').each(function () {
        $(this).removeClass('active');
    });
    //add active class to clicked item
    $(this).parent().addClass('active');
    var target = this.hash;
    var $target = $(target);
    $('html, body').stop().animate({
        'scrollTop': $target.offset().top - $offset
    }, 500, 'swing', function () {
        if (history.replaceState) {
            history.replaceState(null, "", target);
        }
        //reactivate scrollspy
        $('nav').addClass('spy-active');
    });
});

my site is here

Community
  • 1
  • 1
Zac
  • 984
  • 14
  • 25

1 Answers1

2

This line is executed in IE right when you click on a navigation link:

history.replaceState(null, "", $('a[href*=#]:not([href=#])', e.target).attr("href"));

If no links are found inside e.target the result for .attr("href") is undefined. So you'll need to check if the link is found and then call history.replaceState:

var matchLink = $('a[href*=#]:not([href=#])', e.target);
if(matchLink.length) {
    history.replaceState(null, "", matchLink.attr("href"));
}
Inferpse
  • 4,135
  • 1
  • 31
  • 39