0

I'm trying to update the location.hash by checking what div is currently active in a long scrolling site. This works fine is chrome, but is failing in Firefox and IE. I have tested with console.log and I am able to see the id in console, but as soon as I try to feed this into the location hash the scrolling ceases to work on the page, or jumps around unpredictably!

$(window).scroll(function () {
$('div').each(function(){
    if (
      $(this).attr('class')=='article' && $(this).offset().top < window.pageYOffset + 10 
    && $(this).offset().top + $(this).height() > window.pageYOffset + 10
    ) {
       window.location.hash = $(this).attr('id')
    }
});

});
Melzee
  • 91
  • 8

1 Answers1

2

First you need to understand that the scroll event fires many times a second. Combine that with the methodology you are using to search the DOM... look for every div, then filter all those div's for the ones you want and do this all many times a second...you are overloading the browser needlessly.

Scroll the window in this simple demo and see how often your script is firing; http://jsfiddle.net/tRx2P/

If you are going to search the DOM for the same elements repeatedly, caching them into variables will give a big performance boost. Searching the DOM is a lot more expensive than searching a cached variable containing elements

/* use jQuery selector that already filters out all the other `div` in page*/
var $articles= $('.article');
/* now use the variable inside your functions*/
$( window).scroll(function(){
    $articles.each(.....
    /* use the same cache principles for "$(this)" to help avoid needless function calls*/
})

Now the really important part is you should throttle back the number of times a second these need to be checked. There is no benefit in updating the hash multiple times while the user is still scrolling...and overloading the browser to do it

This modification of the demo only fires the code when user hasn't scrolled for 300ms which could likely be increased to 1/2 second or even more. It does this by constantly setting a timeout delay http://jsfiddle.net/tRx2P/2/

You should be able to now adapt these concepts to the code you have

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • Thanks for your help! As you can see I have limited javascript experience. I can see how the checkDelay function in the fiddle works, but I am unsure about how to integrate the two functions. – Melzee Nov 05 '12 at 05:51
  • Thanks again charlietfl for you help! I have been able to get this working, however the page still jumps in ie 9, I have discovered that it is because I am trying to set the hash to an id that exists in the page, so this is confusing the browser. I found this: http://stackoverflow.com/questions/1489624/modifying-document-location-hash-without-page-scrolling but I'm having trouble with the hash being 'not defined' – Melzee Nov 06 '12 at 01:22