I have no idea how I should even call this problem … the title of this question doesn't make any sense at all, I know!
Following case: I have a single-page layout where users scroll downwards. I have sections .layer
which, when inside the viewport should change the hash in the addressbar to its id
. So e.g. the .layer#one
is inside the viewport the url in the addressbar looks like this www.whatever.com/#!/one
$(window).scroll(function() {
hash = $('.layer:in-viewport').attr('id');
top.location.hash = "!/" + hash;
});
This works just fine and is exactly like I want it. The reason I have this syntax with the !/
is that if I would simply set the location to hash
only the scroll-behaviour would be buggy because the browser tries to stick to the hash position.
The problem is now, that I want to be able to make browser history-back button working!
This would normally be rather simple with the hashchange
function that comes with jQuery like so…
$(window).bind( 'hashchange', function( event ) {
//query the hash in the addressbar and jump to its position on the site
});
The only problem I have with this is that the hashchange function would also be triggered if the hash is changed while scrolling. So it would again jump or stick to the current position in the browser. Any idea how I could solve this? I could probably unbind the hashchange while scrolling, right? But is this the best solution?
Sure, you could just unbind and rebind whenever the hash changes on scroll. For example:
var old_hash;
var scroller = function() {
hash = $('.layer:in-viewport').attr('id');
if ( old_hash != hash ) {
$(window).off('hashchange', GoToHash); // using jQuery 1.7+ - change to unbind for < 1.7
top.location.hash = "!/" + hash;
setTimeout(function() { // ensures this happens in the next event loop
$(window).on('hashchange', GoToHash);
}, 0);
old_hash = hash;
}
}
var GoToHash = function() {
//query the hash in the addressbar and jump to its position on the site
}
$(window).scroll(scroller);