0

I created a script to fade in a scroll to top button when $(document).scrollTop() > 100, and fade it out when this is not true. This is done by:

 $.fn.scrollToTop = function() {
     $(window).scroll(function() {
            if( $(this).scrollTop() > 100) {
                $('.scroll-back').fadeIn();
            } else {
                $('.scroll-back').fadeOut();
            }
     });
 }

and to use it I do:

 $(document).ready(function() {
   $(document).scrollToTop();
 }

The button works fine when just scrolling, but if I resize my window / open inspect element when scrolled to the top of the page, the button fades out then fades back in rapidly, any ideas how can I fix this?

  • This is likely happening because the browser is firing the scroll event because the height of the document is changing because of the resize and the inspector highlighting things. You'll need to inhibit your scroll handler under certain conditions. – jwatts1980 Aug 04 '14 at 22:35
  • I looked at an example (here: http://www.paulund.co.uk/playground/demo/jquery_scroll_to_top/) which does this in exactly the same way, but if I resize the window, the button does not fade in, like it does for me – user3624205 Aug 04 '14 at 22:42

2 Answers2

0

The .scroll() event happens many, many times during a scroll. Thus you are constantly queueing up a whole bunch of fade events. Probably the best thing to do would be to use a timer to know when the scrolling has actually stopped and only trigger your fade just once when the scroll has actually stopped.

But, you can at least avoid the backup of fade events by adding .stop(true):

$.fn.scrollToTop = function() {
     $(window).scroll(function() {
            if( $(this).scrollTop() > 100) {
                $('.scroll-back').stop(true).fadeIn();
            } else {
                $('.scroll-back').stop(true).fadeOut();
            }
     });
 }

You can see a plugin method that waits until the scroll has stopped before triggering your event in this post: More efficient way to handle $(window).scroll functions in jquery?

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Sorry, I missed out the `stop()`, I actually do `$('.scroll-back').stop().fadeOut();`, but not on the `fadeIn()`, because it can look ugly. – user3624205 Aug 04 '14 at 22:38
  • @user3624205 - you need to first argument to `.stop(true)` set to `true` in order to clear the animation queue. Your best bet would be to use the `.scrolled()` jQuery method in the post I referenced. Then you won't be changing the fade hundreds of times during a scroll. – jfriend00 Aug 04 '14 at 22:42
  • and as I said, the problem isn't with the scrolling, just resizing – user3624205 Aug 04 '14 at 22:47
  • @user3624205 - Unless you have other code on the resize event, that's probably because you're getting scroll events when resizing, right? So, preventing multiple scroll events would clean that up too. – jfriend00 Aug 04 '14 at 22:48
  • I'm not getting scroll events when resizing. I just checked. – user3624205 Aug 04 '14 at 22:55
  • @user3624205 - then who is triggering fade animations upon resize - the whole point of the question seems entirely lost now. You show fade code, but now you say that it isn't getting called. Do you have window resize handling code somewhere that might be causing your issue? – jfriend00 Aug 04 '14 at 23:08
  • This is the reason I asked the question. This makes no sense to me at all. I've checked over my code over and over again and can't seem to find anything wrong with it. – user3624205 Aug 04 '14 at 23:13
  • @user3624205 - I'd suggest putting a breakpoint in the jQuery `.fadeOut()` function and when the breakpoint is hit, you look up the stack trace and see who's calling it. – jfriend00 Aug 04 '14 at 23:23
  • Thanks - I've solved the issue now... And I feel very stupid. There was a fadeIn() in the wrong place in a completely different function – user3624205 Aug 04 '14 at 23:47
  • @user3624205 - you should either delete your question, pick one of the existing answers or post your own answer and then select it as the best answer. In either case, your question here should get resolved since you're now done with the issue. – jfriend00 Aug 05 '14 at 07:56
0

In my opinion, there is a better way to achieve what you're trying to do.

Instead of using JavaScript to do the fade animation, use CSS transitions. Then use JavaScript to add/remove a class to each button depending on the scroll position.

CSS:

.scroll-back {
    /* Existing style... */
    opacity: 1.0;
    transition: opacity ease-in-out 400ms;
}
.scroll-back.hide {
    opacity: 0;
}

JavaScript:

$(window).scroll(function() {
    if( $(this).scrollTop() > 100) {
        $('.scroll-back').removeClass('hide');
    } else {
        $('.scroll-back').addClass('hide');
    }
});

I find CSS transition animations to be much faster than jQuery animations, and they're much more robust when it comes to stopping/starting/resuming animation.

The Maniac
  • 2,628
  • 3
  • 19
  • 29