带有promise的jQuery动画回调仍然过早发生

时间:2014-02-20 09:24:53

标签: javascript jquery animation callback

如果点击菜单中的徽标,我会重新滚动主页。我还在$(window).scroll()上有一个监听器,它以一个负余量为屏幕外的对象设置动画。

我的问题是这个事件是通过动画触发的(动画scrollTop)。

这不应该发生,因为我有一个布尔变量必须为true才能执行此操作,我只在使用.promise().done()的组合滚动动画后将其设置为true。 / p>

这是我的JavaScript:

var firstscroll=true;

$(function(){


    var captionWidth= $(".caption").children().size() * 35;
    $(".caption").width(captionWidth);

    $(window).scroll(function() {
      if(firstscroll){
        $(".hidden-menu").removeClass("hidden-menu", {duration:500});
        $('.header').animate({
            marginTop: $('.header').height() * -1
         }, 500);
         $('html, body').animate({
            scrollTop: 0
         }, 500);
         firstscroll = false;
      }
    });

    $(".menu-logo, .logo-container").click(function(){
        $('.header').animate({
            marginTop: 0
         }, 500);
         $('html, body').animate({
            scrollTop: 0
            }, 500).promise().done(resetFirstScroll());
    });
});

var resetFirstScroll = function() {
  firstscroll=true;
}

解决方案是给函数一个50毫秒的setTimeout,但我宁愿在动画完成后正确执行它。

使用标准回调提供相同的输出:

    $(".menu-logo, .logo-container").click(function(){
        $('.header').animate({
            marginTop: 0
         }, 500);
         $('html, body').animate({
            scrollTop: 0
            }, 500, function() {
                resetFirstScroll();
            });
    });
});

var resetFirstScroll = function() {
  firstscroll=true;
}

1 个答案:

答案 0 :(得分:0)

对于那些想要“hacky”解决方案的人:

var firstscroll=true;

$(function(){


    var captionWidth= $(".caption").children().size() * 35;
    $(".caption").width(captionWidth);

    $(window).scroll(function() {
      if(firstscroll){
        $(".hidden-menu").removeClass("hidden-menu", {duration:500});
        $('.header').animate({
            marginTop: $('.header').height() * -1
         }, 500);
         $('html, body').animate({
            scrollTop: 0
         }, 500);
         firstscroll = false;
      }
    });

    $(".menu-logo, .logo-container").click(function(){
        $('.header').animate({
            marginTop: 0
         }, 500);
         $('html, body').animate({
            scrollTop: 0
            }, 500, function() {
            setTimeout( resetFirstScroll, 50 );
            });
    });
});

var resetFirstScroll = function() {
  firstscroll=true;
}