davist11/jQuery-One-Page-Nav

Changing url on scroll [SOLVED]

Rechtsamwald opened this issue · 7 comments

Added a command changing the url on scroll. It's adding the name (the id) of the current focused section to the url each time you scroll. Since several people seem to need it, it could be adjusted in future versions.

In this part:

    scrollChange: function() {
        var windowTop = this.$win.scrollTop();
        var position = this.getSection(windowTop);
        var $parent;
        //If the position is set
        if(position !== null) {
            $parent = this.$elem.find('a[href$="#' + position + '"]').parent();
            //If it's not already the current section
            if(!$parent.hasClass(this.config.currentClass)) {
                //Change the highlighted nav item
                this.adjustNav(this, $parent);
                //If there is a scrollChange callback
                if(this.config.scrollChange) {
                    this.config.scrollChange($parent);
                }
            }
        }
    },

just add the following lines:

    scrollChange: function() {
        var windowTop = this.$win.scrollTop();
        var position = this.getSection(windowTop);
        var $parent;
        //If the position is set
        if(position !== null) {
            $parent = this.$elem.find('a[href$="#' + position + '"]').parent();
            //If it's not already the current section
            if(!$parent.hasClass(this.config.currentClass)) {
                //Change the highlighted nav item
                this.adjustNav(this, $parent);

// ADD THIS TWO LINES TO CHANGE THE URL ON SCROLL !
var theHash = position;
window.location.hash = theHash;


                //If there is a scrollChange callback
                if(this.config.scrollChange) {
                    this.config.scrollChange($parent);
                }
            }
        }
    },

Best regards,
Rechtsamwald

Exactly what I asked before. Thanks!

@Rechtsamwald Thanks for this solution.

When I implemented your code, the hash did update. But now I've got an annoying jumpy effect when the hash updates (in each browser). Don't you have this?

@Freekbron, me too. I think this is because browser tries to jump to the anchor. Has anyone a solution?

Maybe something like this?
But I think it doesnt work in older browsers.

    adjustNav: function(self, $parent) {
        self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
        $parent.addClass(self.config.currentClass);

        var link= $parent.attr('data-menuanchor');
        var newLoc = '#' + link;

        if(self.config.changeHash) {
            history.pushState(1,1,newLoc);
        }
    }

@ixlipixli, this way is not need use the attr data:

adjustNav: function(self, $parent) {
    self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
    $parent.addClass(self.config.currentClass);

     var link= $parent[0].firstElementChild.hash;

      if(self.config.changeHash) {
             history.pushState(1,1,link);
      }
}

Work IE10+ (and other browsers)

To work in IE9, replace this

history.pushState(1,1,link);

to

window.location.hash = link;

Lol im confused. Is there a complete js example that I can just copy and paste?

@Steve2428

Please add the following code on scrollChange event:
window.location.hash = $currentListItem.find('a').attr('href');

Here is the default initialisation with the above line added:

$('#nav').onePageNav({
	currentClass: 'current',
	changeHash: false,
	scrollSpeed: 750,
	scrollThreshold: 0.5,
	filter: '',
	easing: 'swing',
	begin: function() {
		//I get fired when the animation is starting
	},
	end: function() {
		//I get fired when the animation is ending
	},
	scrollChange: function($currentListItem) {
		window.location.hash = $currentListItem.find('a').attr('href');
	}
});