jQuery scrollTop()在滚动方向更改

时间:2017-11-18 21:52:31

标签: javascript jquery scroll

我试图通过jQuery"滚动"来获得正确的滚动方向。事件

为此,我在这里使用解决方案:https://stackoverflow.com/a/4326907/8407840

但是,如果我更改滚动的方向,则scrollTop返回的偏移量第一次不正确。这会导致以下行为:

  1. 向下滚动 - >
  2. 向下滚动 - >向下
  3. 向上翻转 - >向下
  4. 向上翻转 - >达
  5. 向下滚动 - >达
  6. 向下滚动 - >向下
  7. ......等等,我想你明白了。
  8. 
    
    var ACTIVE_SECTION = null;
    var ANIMATION_DURATION = 700;
    
    $(document).ready(function() {
      ACTIVE_SECTION = $("section:first-of-type").get(0);
      var prevPosition = $(window).scrollTop();
      
      $(window).on("scroll", function() {
        doScrollingStuff(prevPosition);
      });
    
    });
    
    function doScrollingStuff(prevPosition) {
      var ctPosition = $(window).scrollTop();
      var nextSection = ACTIVE_SECTION;
      
      // Remove and re-append event, to prevent it from firing too often.
      $(window).off("scroll");
      setTimeout(function() {
        $(window).on("scroll", function() {
          doScrollingStuff(prevPosition);
        });
      }, ANIMATION_DURATION + 100);
    
      // Determine scroll direction and target the next section
      if(ctPosition < prevPosition) {
        console.log("up");
        nextSection = $(ACTIVE_SECTION).prev("section").get(0);
      } else if(ctPosition > prevPosition) {
        console.log("down");
        nextSection = $(ACTIVE_SECTION).next("section").get(0);
      }
      
      // If a next section exists: Scroll to it!
      if(typeof nextSection != 'undefined') {
        var offset = $(nextSection).offset();
        $("body, html").animate({
          scrollTop: offset.top
        }, ANIMATION_DURATION);
        ACTIVE_SECTION = nextSection;
      } else {
        nextSection = ACTIVE_SECTION;
      }
    
      console.log(ACTIVE_SECTION);
      prevPosition = ctPosition;
    }
    &#13;
    section {
      width:100%;
      height:100vh;
      padding:60px;
      box-sizing:border-box;
    }
    
    section:nth-child(1) { background:#13F399; }
    section:nth-child(2) { background:#14FD43; }
    section:nth-child(3) { background:#4EE61E; }
    section:nth-child(4) { background:#BEFD14; }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <section id="sect1">Section 1</section>
    <section id="sect2">Section 2</section>
    <section id="sect3">Section 3</section>
    <section id="sect4">Section 4</section>
    &#13;
    &#13;
    &#13;

    这是一支笔,您可以在其中查看我的实施:https://codepen.io/EigenDerArtige/pen/aVEyxd

    我试图完成对下一个或上一个部分的自动滚动,无论何时用户滚动或向上/向下滑动...因此我每秒只触发&#34;滚动&#34; -event一次,以防止多个scrolljacks一次全部发生......但是上述行为似乎导致用户滚动到错误的部分。

    我现在已经尝试了几个小时才能让它正常工作,但无济于事。非常感谢帮助!

1 个答案:

答案 0 :(得分:1)

问题在于作业prevPosition = ctPosition

每次滚动处理程序运行时,var ctPosition = $(window).scrollTop();都有助于确定滚动方向,但是它应该作为prevPosition重新记忆的值。

完成动画后,

prevPosition必须为$(window).scrollTop()

试试这个:

$(document).ready(function() {
    var ANIMATION_DURATION = 700;
    var ACTIVE_SECTION = $("section:first-of-type").eq(0);
    var prevPosition = $(window).scrollTop();
    $(window).on("scroll", doScrollingStuff);

    function doScrollingStuff(e) {
        $(window).off("scroll");

        var ctPosition = $(window).scrollTop();
        var nextSection = (ctPosition < prevPosition) ? ACTIVE_SECTION.prev("section") : (ctPosition > prevPosition) ? ACTIVE_SECTION.next("section") : ACTIVE_SECTION; // Determine scroll direction and target the next section

        // If next section exists and is not current section: Scroll to it!
        if(nextSection.length > 0 && nextSection !== ACTIVE_SECTION) {
            $("body, html").animate({
                'scrollTop': nextSection.offset().top
            }, ANIMATION_DURATION).promise().then(function() {
                // when animation is complete
                prevPosition = $(window).scrollTop(); // remember remeasured .scrollTop()
                ACTIVE_SECTION = nextSection; // remember active section
                $(window).on("scroll", doScrollingStuff); // no need for additional delay after animation
            });
        } else {
            setTimeout(function() {
                $(window).on("scroll", doScrollingStuff);
            }, 100); // Debounce
        }
    }
});