Mousewheel scrollTop not updating after height resize

167 Views Asked by At

I have 3 sections on a webpage that are shown and hidden based on a corresponding button click. Following a click the currently visible area fades out, the area resizes to fit the height of the new content, then the new area fades in, and then the window animates a scrollTop so that the buttons are at the top of the screen. Above all of this there is a large image slider, the menu and the logo.

This works fine except and looks pretty cool.

But, apparently if the new height is shorter than the previous height the scrollTop value fails to update when the mousewheel is used, ( for only a few loops ). The visible result is the page moving down a bit the jumping back to its previous position for a few loops.

So, for example, if I dump the scrollTop position to the console and scroll the wheel it will display: 535 535 535 535 535 556 593 619 ...

In the past I might have simply used fadeIn and fadeOut. This would resize the sections automatically. But with the addition of the scrollTop animation after the fade this seems to cause issues with the animation ( fadeIn/Out uses display:none so I guess) The result is that the animation goes to the wrong position on the page.

Any help is greatly appreciated

/**
 * toggle
 *
 * there are three sections sitting on top of each other
 * when a button is clicked the sections
 * a - fade out
 * b - resize ( the footer will move up and down to fit)
 * c - fade in
 * d - the page will scroll to this section which is directly under the header slider
 *
 * d is the reason I am using opacity and resizing instead of a simple fadeOut because display:none
 * has no height information and makes the scroll animation wonky
 * 
 * @returns {Void}
 * */
var toggle = function(e) {
    e.preventDefault();

    // reset section
    $('.sections a').removeClass('show');

    // get the target top position for the animation
    var top = $('.logo-container').position().top;

    // get the class name of the click
    var t = $(this).attr("class");

    // dealing with other classes (unrelated)
    if ($(this).hasClass('in')) {
      t = t.replace('in i-','');
      $('.sections .'+t).addClass('show');
    }else{
      $(this).addClass('show'); 
    }

    // push all sections to the same z-index
    $('.container section').css('z-index',1);

    // fade out sections and update
    $('.container section.show').fadeTo("fast",0,function() {

        $(this).removeClass("show");

        $('.container .'+t).addClass("show");

        // sections is assigned at load time with each sections height
        var h = sections[t]+150; // +150 just gives us a little breathing room

        $('.container, .container section').animate({'height': h},100,function(){
          // set this sections z-index above the rest
          $('.container .'+t).css('z-index',2);
          // fade in the relevant section
          $('.container .'+t).fadeTo("fast",1,function() {
            // scroll the mouse postion to the content
            $("html, body").animate({ 
              scrollTop: top+'px' 
            }, 500,function() {
              // assign the scrolltop position for an unrelated bit of code
              opt = $(document).scrollTop();

            });
          });
        });
    });
}

/**
* bindActions
* bind events to dom nodes
* @returns {Void}
* */ 
var bindActions = function() {
    if (!loggedin) {
        $('.sections a, section a.in').on('click', toggle);
    }
};
0

There are 0 best solutions below