【问题标题】:jquery scrolltop() returns value of previous scroll positionjquery scrolltop() 返回上一个滚动位置的值
【发布时间】:2016-04-09 14:48:14
【问题描述】:

我正在使用 jquery 函数 element.scrollTop() 使用以下行获取页面的当前滚动位置:

var currentScrollPosition=  $('html').scrollTop() || $('body').scrollTop();

但它总是返回上一个滚动位置的值。请检查下面的代码(与in here 相同)。 正如您可以自己尝试并在代码中看到的那样,在每次微小滚动之后,我们都会得到以下一系列值:

(1:当代码第一次运行并且还没有移动时)

增量:0

累积增量:0

functionCallCount:0

当前滚动位置:0

(delta 给出滚动量,cumulativeDelta 给出滚动总量,functionCallCount 是您滚动的次数,currentScrollPosition 是 scrolltop() 返回的值)

(2:稍微滚动时)

增量:-120

累积增量:-120

functionCallCount:1

当前滚动位置:0

(注意这里,currentScrollPosition 还没有更新)

(3:再滚动一点)

增量:-120

累积增量:-240

functionCallCount:2

当前滚动位置:90.90908893868948

(这里,累积增量,即到目前为止所做的总滚动量加倍,并且 currentScrollPosition 是第一次更新)

(4:再滚动一点)

增量:-120

累积增量:-360

functionCallCount:3

当前滚动位置:181.81817787737896

(现在,cumulativeDelta 增加了三倍,而 currentScrollPosition 增加了一倍。因此,这是两次滚动后的值,但在 3 次滚动后更新)

我为冗长的问题道歉,但否则很难问。我想知道为什么会发生这种情况,如果我应该以其他方式使用此功能,还有其他替代方法。

document.addEventListener("mousewheel", MouseWheelHandler);
var cumulativeDelta = 0,
  functionCallCount = 0;

function MouseWheelHandler(e) {
  e = window.event || e; // 'event' with old IE support
  var delta = e.wheelDelta || -e.detail; // get delta value

  cumulativeDelta += delta;
  functionCallCount += 1;
  currentScrollPosition = $('html').scrollTop() || $('body').scrollTop();

  document.getElementById("info1").innerHTML = "delta:" + delta;
  document.getElementById("info2").innerHTML = "cumulativeDelta:" + cumulativeDelta;
  document.getElementById("info3").innerHTML = "functionCallCount:" + functionCallCount;
  document.getElementById("info4").innerHTML = "currentScrollPosition:" + currentScrollPosition;

}
body {
  height: 2000px;
  border: solid red 3px;
}
.normalPart {
  border: solid green 2px;
  height: 900px;
}
.stationary {
  position: fixed;
  top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<div class="stationary">
  <div id="info1"></div>
  <div id="info2"></div>
  <div id="info3"></div>
  <div id="info4"></div>
</div>

【问题讨论】:

    标签: javascript jquery html scroll scrolltop


    【解决方案1】:

    问题是因为当鼠标滚轮移动开始时会触发鼠标滚轮事件。您正在阅读scrollTop 在更新发生之前之前。您需要使用计时器来获取scrollTop 鼠标滚轮滚动完成之后。试试这个:

    document.addEventListener("mousewheel", MouseWheelHandler);
    var cumulativeDelta = 0,
        functionCallCount = 0,
        currentScrollPosition = 0;
    
    function MouseWheelHandler(e) {
        e = window.event || e; // 'event' with old IE support
        var delta = e.wheelDelta || -e.detail; // get delta value
    
        cumulativeDelta += delta;
        functionCallCount += 1;
    
        setTimeout(function() {
            currentScrollPosition = $(window).scrollTop();
            document.getElementById("info4").innerHTML = "currentScrollPosition:" + currentScrollPosition;
        }, 200); // update currentScrollPos 200ms after event fires
    
        document.getElementById("info1").innerHTML = "delta:" + delta;
        document.getElementById("info2").innerHTML = "cumulativeDelta:" + cumulativeDelta;
        document.getElementById("info3").innerHTML = "functionCallCount:" + functionCallCount;
    }
    body {
      height: 2000px;
      border: solid red 3px;
    }
    .normalPart {
      border: solid green 2px;
      height: 900px;
    }
    .stationary {
      position: fixed;
      top: 0px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    <div class="stationary">
      <div id="info1"></div>
      <div id="info2"></div>
      <div id="info3"></div>
      <div id="info4"></div>
    </div>

    或者,您可以直接在窗口的滚动事件上读取currentScrollTop 位置,因为它始终与其当前位置同步。

    【讨论】:

    • 这真是太棒了!正是我想要的:) ...也有解释。感谢您快速准确的回复.. 将尝试实施。
    • 没问题,很乐意提供帮助。
    • 只是想知道,选择 200ms 有什么特别的理由吗?我尝试了更短的时间,并且得到了 currentScrollPosition 的不同值。例如。 50ms 延迟导致 0.09 左右,而 100ms 导致 0.6。实际结果应为 0.90-0.95。因此,滚动过程似乎需要大约 200 毫秒才能完成。实际上,我想在这个计算之后运行进一步的代码。我希望在特定的滚动值之后,鼠标滚轮滚动应该导致水平滚动,而其他一些值则恢复正常滚动。但是添加延迟不会使其成为实时。你能推荐点什么吗?
    • 如果你降低延迟,滚动的动画仍然在进行中,因此你会看到不同的值。我使用了 200 毫秒,因为这似乎是过渡结束的最低但最可靠的时间。如果要实时查看实际滚动位置,直接钩住窗口的scroll事件即可。
    • yupp .. jsfiddle.net/5r74m54x/2 这大大简化了工作.. 再次感谢:) .. 只是好奇.. 浏览器在这种方法中的工作方式有何不同??
    【解决方案2】:

    我会监听scroll 事件而不是wheelscrollTop 值更新后,滚动激活。

    target.onscroll = functionRef

    很好的例子here

    【讨论】:

      猜你喜欢
      • 2015-01-25
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多