Search code examples
javascriptjqueryhtmlscrollfade

FadeIn & fadeOut happens multiple time after window scroll


I am trying to change the logo image src if not window scrollTop and backwards with a fadeIn and fadeOut effect, but even if you scroll once, fadeIn & Out happens multiple times.

I figured out with console.log that even if you scroll once (mousewheel or arrows), it logs many times the message (like 8,10 or 15 times). That means that the logo flashes always 10+ times before changing the src to the other image.

jQuery:

$(window).scroll(function () {
    if ($(window).scrollTop()) {
        $.when($('#navbar').css('padding', '0px')).done(function () {
            $('.logo img').fadeOut(400, function () {
                $('.logo img').attr('src', 'images/small-logo.png');
                console.log('bot');
            }).fadeIn();
        });
    } else {
        $.when($('#navbar').css('padding', '20px 0px')).done(function () {
            $('.logo img').fadeOut(400, function () {
                $('.logo img').attr('src', 'images/top-logo.png');
                console.log('top');
            }).fadeIn();
        });
    }
});

HTML:

<div class="col-lg-12">
   <div class="col-lg-3 logo no-padding-left">
      <a href="index.php">
        <img src="images/logo.png"/>
      </a>
   </div>
   <div class="col-lg-9 no-padding-right">
      <div class="navbar-header">
        <div id="navbar" class="navbar-collapse collapse">
           <ul class="nav navbar-nav">
               .
               .
               .
           </ul>
        </div>
     </div>
   </div>
</div>

I've found and tried many solutions (like .stop(), if animated etc), but nothing seemed to work for me and i don't know why.

Thank you in advance.


Solution

  • the problem can be solved using a flag that checks if the page is scrolled to the top or not.

    You just have to change your JS code like this:

    $isScrolledToTop = false;
    
    $(window).scroll(function () {
        if ($(window).scrollTop()){
            if($isScrolledToTop == false) {
                $.when($('#navbar').css('padding', '0px')).done(function () {
                    $('.logo img').fadeOut(400, function () {
                        $('.logo img').attr('src', 'images/small-logo.png');
                        console.log('bot');
                    }).fadeIn();
                });
                $isScrolledToTop = true;
            } 
        } else {
            if($isScrolledToTop == true){
                $.when($('#navbar').css('padding', '20px 0px')).done(function () {
                    $('.logo img').fadeOut(400, function () {
                        $('.logo img').attr('src', 'images/small-logo.png');
                        console.log('top');
                    }).fadeIn();
                });
                $isScrolledToTop = false;
            }
        }
    });
    

    In this way you perform image change only in two situations:

    • You move away from top of the page
    • You get back to top of the page

    Try it, it should work!

    Bye