jQuery scrollTop()在滚动方向更改时返回错误的偏移量 [英] jQuery scrollTop() returns wrong offset on scroll-direction change

查看:77
本文介绍了jQuery scrollTop()在滚动方向更改时返回错误的偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过jQuery的"scroll"事件获取正确的滚动方向.

I'm trying to get the correct scroll direction via jQuery's "scroll" event.

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

For this, I'm using the solution here: https://stackoverflow.com/a/4326907/8407840

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

However, if I change the direction of my scroll, the offset returned by scrollTop is incorrect on the first time. This results in the following behavior:

  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/笔/aVEyxd

Here's a pen, where you can see my implementation: https://codepen.io/EigenDerArtige/pen/aVEyxd

每当用户滚动或向上/向下滑动时,我都试图完成对下一个或上一个部分的自动滚动.因此,我仅每秒触发一次"scroll"事件,以防止在一次...但是,以上行为似乎导致用户滚动到错误的部分.

I am trying to accomplish an autoscroll to the next or previous section, whenever the user scrolls or swipes up/down... Therefore I only fire the "scroll"-event once every second, to prevent multiple scrolljacks all happening at once... However the above behavior seems to result in the user being scrolled to the wrong section.

我已经尝试了几个小时才能使其正常运行,但无济于事.非常感谢您的帮助!

I've been trying for a couple of hours now to get it working, but to no avail. Help is greatly appreciated!

推荐答案

问题出在赋值prevPosition = ctPosition.

每次滚动处理程序运行时,var ctPosition = $(window).scrollTop();都可以确定滚动方向,但是不是应当记住的值为prevPosition.

Each time the scroll handler runs, var ctPosition = $(window).scrollTop(); is good for determining scroll direction, however it's not the value that should be rememberad as prevPosition.

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

prevPosition needs to be $(window).scrollTop() as measured after the animation has completed.

尝试一下:

$(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
        }
    }
});

这篇关于jQuery scrollTop()在滚动方向更改时返回错误的偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆