【问题标题】:$('body, html').is(':animated')) doesn't seem to be working$('body, html').is(':animated')) 似乎不起作用
【发布时间】:2016-05-28 09:58:41
【问题描述】:

我有 4 个高度设置为窗口高度的 div。我希望在每次向下滚动时滚动到下一个,但是在第一次向下滚动之后它只是继续滚动,似乎忽略了is:animated

<style>

    .div {
        width: 100%;
    }

    .red {
        background: red;
    }

    .yellow {
        background: yellow;
    }

    .green {
        background: green;
    }

    .blue {
        background: blue;
    }

</style>

<div id="id0" data-id="0" class="nbhd red scrolledto"></div>
<div id="id1" data-id="1" class="nbhd yellow"></div>
<div id="id2" data-id="2" class="nbhd green"></div>
<div id="id3" data-id="3" class="nbhd blue"></div>



function setHeights() {
        $('.nbhd').css('height', window.innerHeight);
    }

    function scrollSections() {

        if ($('body, html').is(':animated')) {
            return;
        }

        var currentSectionId = $('.nbhd.scrolledto').data('id');

        currentSectionId++;

        $('.scrolledto').removeClass('scrolledto');

        var section = $('#id'+currentSectionId);

        section.addClass('scrolledto');

        var pos = section.offset().top;

        $('body, html').animate({scrollTop: pos}, 1000, function() {
            console.log('animated');
        });

    }

    setHeights();



    $( window ).on( "scroll", function() {
        scrollSections();
    });

小提琴:https://jsfiddle.net/2d47k6af/

由于某种原因,我还收到了 6 次 animated 记录,我预计是 3 次。

【问题讨论】:

  • 您已记录了 6 次 animated,因为 body 记录了 3 次,html 记录了 3 次
  • 哦,谢谢。
  • 您可以使用全局变量来解决您的问题:在脚本顶部定义var isAnimated = false;$(window).on('scroll') 时设置为真;并在$('html, body').animate()的回调中将其重置为false
  • 不起作用,如果我这样做,它甚至不会一开始就触发。

标签: javascript jquery


【解决方案1】:

我想这就是你想要的:https://jsfiddle.net/2d47k6af/5/

问题是你不能distinguish scroll events triggered by JavaScript and by user themself。因此,当您运行动画时,它触发了许多 $(window).on("scroll", ...); 事件,由于 $('body, html').is(':animated') 按预期工作,这些事件被忽略了。

但是最后一次滚动事件可能发生在动画结束之后,所以函数scrollSections() 被再次调用,触发了另一个动画,依此类推。我的解决方案是在动画结束后和其他用户触发滚动之前添加一个短暂的超时:

$('body, html').animate({scrollTop: pos}, 1000, function() {
  console.log('animated');
  ignoreScrollEvents = true;

  setTimeout(function() {
    ignoreScrollEvents = false;
  }, 100);

});

【讨论】:

    【解决方案2】:

    你可以使用变量来实现你想要的:

    function setHeights() {
      $('.nbhd').css('height', window.innerHeight);
    }
    
    
    var isAnimated = false; // Initialize variable
    function scrollSections() {
      if (isAnimated) return; // Previous animation still in action
      isAnimated = true; // lock it
      var currentSectionId = $('.nbhd.scrolledto').data('id');
    
      currentSectionId++;
      var section = $('#id'+currentSectionId);
      if (!section.length) {
        currentSectionId = 0;
        section = $('#id0');
      }
    
      $('.scrolledto').removeClass('scrolledto');
    
      section.addClass('scrolledto');
    
      var pos = section.offset().top;
    
      $('body').animate({scrollTop: pos}, 1000, function() {
          setTimeout(function(){
            isAnimated = false; // unlock it on next eventloop tick
          })
      });
    }
    
    setHeights();
    
    
    
    $( window ).on( "scroll", function() {
        scrollSections();
    });
    .div {width: 100%;}
    .red {background: red;}
    .yellow {background: yellow;}
    .green {background: green;}
    .blue {background: blue;}
    <div id="id0" data-id="0" class="nbhd red scrolledto"></div>
    <div id="id1" data-id="1" class="nbhd yellow"></div>
    <div id="id2" data-id="2" class="nbhd green"></div>
    <div id="id3" data-id="3" class="nbhd blue"></div>
    
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-28
      • 2021-11-27
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 2016-02-01
      相关资源
      最近更新 更多