javascript - jQuery scrollTop() 在滚动方向改变时返回错误的偏移量

标签 javascript jquery scroll

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

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

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

  1. 车轮向下 -> 向下
  2. 车轮向下 -> 向下
  3. 轮子向上 -> 向下
  4. 向上转动 -> 向上
  5. 轮子向下 -> 向上
  6. 车轮向下 -> 向下
  7. ...等等,我想你明白了。

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;
}
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; }
<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>

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

每当用户滚动或向上/向下滑动时,我正在尝试完成到下一个或上一个部分的自动滚动...因此我每秒只触发一次“滚动”事件,以防止多个 scrolljacks 发生在一次...但是,上述行为似乎导致用户滚动到错误的部分。

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

最佳答案

问题出在赋值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
        }
    }
});

关于javascript - jQuery scrollTop() 在滚动方向改变时返回错误的偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47371449/

相关文章:

php - Ajax 正在躲避我。如何执行一个简单的ajax请求?

javascript - 当部分顶部等于或高于主面板顶部时发出类警报

python - Pyautogui滚动微调?

javascript - 如何在不使用 PHP exec 或 shell_exec 的情况下运行 CasperJS 脚本

JavaScript:使用 localStorage 登录/注册

javascript - 使用 react-router 中的 MemoryRouter 使用 javascript 导航

c# - 如何在触摸屏中滚动 ListView

javascript - 可以在自己的容器中使用sqlite吗?

javascript - 导航栏 anchor 填充 div,WordPress 菜单

javascript - 如何执行绑定(bind)到事件的监听器并从执行中排除绑定(bind)到不同事件的其余监听器?