views:

1233

answers:

2

Inside a jQuery event handler, I would like to scroll the window and then add a class to something. This is my code:

$('#foo').click(function() {       
    window.scrollTo(y);
    $('#bar').addClass('active');
});
$(window).scroll(function() {
    $('#bar').removeClass('active');
});

Notice I have another handler to remove that same class whenever the window is scrolled. The scrolling part works fine, but seems to run asynchronously, so removeClass() happens after addClass() but before the scrolling is finished. I don't know how to do this in plain javascript. I know there is a jQuery scrollTop() function that does the same thing (but seems to have cross-browser issues), but it doesn't accept a callback.

What I really need is a callback to add the class after the scrolling is finished. thanks!

A: 

There is a jQuery plugin called scrollTo that provides this capability (along with other features). I recommend using this plugin (check out the onAfter callback config) or check it's source.

Jakub Hampl
thanks. I saw that, but would rather not throw in a bunch of additional code for something I know is simple, I just don't know how to do it.
carillonator
+2  A: 

You can also accomplish this with animate

$('#foo').click(function(){
  var count = 0;
  $('html,body').animate({scrollTop:0},1000,function(){
    count++;
    if (count == 2){
      if (!($('#bar').hasClass('active'))){
        $('.place').each(function(){
          if($(this).hasClass('active')){
            $(this).removeClass('active');
          }
          if($(this).attr('id') == 'bar'){
            $(this).addClass('active');
          }
        });
      }
    }
  });
});

EDIT:

give each possible place that you are "activating" a class. (e.g. 'place')

Then, the above code should work (edited)

Brant
this works, but only sometimes. I'm trying to figure out what causes it.
carillonator
yeah, even as a callback on animate() like this, the scroll() handler still fires after this addClass() has executed.
carillonator
I think I am a little confused as to what you are trying to do exactly. Are you trying to remove the class, then add it?
Brant
when a link is clicked, I want to scroll to a particular place in the window, then add a class to that link to show that it's selected. But, when the window is later scrolled, I want to take that class away to show that it's no longer selected. thanks for the help.
carillonator
Updated the above code to fit your description. Of course, it needs to be edited to fit your exact code.
Brant
I see what you're going for, but I'm pretty sure the problem is that the callback is firing before the scrolling is completely done, meaning the scrolling handler is removing the class that was just added by this animate callback. I see the link flashing the class on and off almost instantly when this happens.
carillonator
Also, is it necessary to check if a class is already there before adding it? Can't you just run addClass() on something, and if it's already there, it will just be harmless and not do anything? Same with removeClass.
carillonator
ok I figured out the problem.....`$('html,body')` fires the whole listener twice, at least in Firefox. According to the comments for the scrollTop() API, there doesn't seem to be any selector that works for all browsers, and now we know using multiple isn't an option.
carillonator
Editing again... just add a counter for the elements its scrolling.
Brant