1

I'm having problems understanding why my toggleClass inside of the function after the animate doesn't seem to trigger properly. When looking at console, you will be able to see that the element menu is changing states, which leads me to think it is toggling both on and off quickly. Once the scroll animation completes, toggleClass works as to be expected.

My script code is as follows:

  $(document).ready(function() {

    // initToggle();
    stickyNav();
    toggleMenu();

  });

  function stickyNav() {

      var navOffset = $('.nav-bar').offset().top;

      $(window).scroll(function() {
          var nav = $('.nav-bar');
          var scroll = $(window).scrollTop();

          if (scroll >= navOffset) {
              nav.addClass('fixed');
          } else {
              nav.removeClass('fixed');
          }
      });
  }

  function toggleMenu() {
      $('.nav-menu').click(function() {
          if (!$('.nav-bar').hasClass('fixed')) {
              $('html, body').animate({scrollTop: $('.nav-bar').offset().top}, '800',
              function() {
                  $('.menu').toggleClass('active');
                  $('body').toggleClass('no-scroll');
              });
          } else {
              $('.menu').toggleClass('active');
              $('body').toggleClass('no-scroll');
          }
      });
  }

HERE is a "working" codepen of my code which better displays the issue I'm having.

ekfuhrmann
  • 1,639
  • 11
  • 12
  • What *exactly* do you expect to happen? List out what you expect to happen, what **is** happening, and the steps to take to see the problem. – Mike Cluck Sep 07 '16 at 20:45
  • I believe your animation fires twice, once for `html` and once for `body`. – showdev Sep 07 '16 at 20:51
  • @showdev That was exactly what the issue was. Boy do I feel silly, considering I even mentioned it looked to be firing twice but couldn't figure out quite why. Also, that second comment of yours regarding the `when` and `then` is really neat. Not sure it's entirely necessary in this instance as I was calling the animate twice, but could be helpful in the future. Thanks a lot for the help! – ekfuhrmann Sep 07 '16 at 21:13
  • This is also relevant: [Callback of .animate() gets called twice jquery](http://stackoverflow.com/questions/8790752/callback-of-animate-gets-called-twice-jquery). – showdev Sep 07 '16 at 21:18

1 Answers1

0

@showdev linked to a similar question relating to using promise().

Got the script to work by changing it to the following:

function toggleMenu() {
    $('.nav-menu').click(function() {
        if (!$('.nav-bar').hasClass('fixed')) {
            $('html, body').animate({scrollTop: $('.nav-bar').offset().top}, '800').promise().done(function() {
                $('.menu').toggleClass('active');
                $('body').toggleClass('no-scroll');
            });
        } else {
            $('.menu').toggleClass('active');
            $('body').toggleClass('no-scroll');
        }
    });
}
ekfuhrmann
  • 1,639
  • 11
  • 12
  • According to [this post](http://stackoverflow.com/questions/19303405/difference-between-html-body-animate-and-body-animate), there may be browser compatibility issues when only using one of the selectors. – showdev Sep 07 '16 at 21:16
  • Yeah, I used the link you suggested and got it to work via `promise()`. I'm going to mark your duplicate as the correct answer. Thanks again! – ekfuhrmann Sep 07 '16 at 21:24