【问题标题】:Detect if element has stopped momentum scrolling?检测元素是否停止动量滚动?
【发布时间】:2012-11-28 13:46:21
【问题描述】:

是否可以通过 Javascript 在 Mobile Safari 中检测元素是否停止滚动?

我有一个元素使用-webkit-overflow-scrolling:touch 进行动量滚动,我需要检测元素是否停止滚动,包括在动量影响滚动之后。

这可能吗?使用 onscroll 事件在我的应用程序中无法正常工作。

【问题讨论】:

    标签: javascript jquery mobile-safari dom-events touch-event


    【解决方案1】:

    您可以计算滑动速度并尝试根据某个阈值确定是否会发生动量滚动。我做了一些测试,大约 0.25 像素/毫秒似乎是一个不错的值。

    注意:有时,较低的速度也会发生动量滚动。我记录的导致动量滚动的最低速度是 0.13(增量时间非常短),所以如果您需要 100% 完美的解决方案,请继续寻找。

    示例代码还检测并处理过度滚动。

    使用 JQuery;

    var scrollWrapper = $('#myWrapper');
    var starTime, startScroll, waitForScrollEvent;
    scrollWrapper.bind('touchstart', function() {
       waitForScrollEvent = false;
    });
    
    scrollWrapper.bind('touchmove', function() { 
      startTime = new Date().getTime(); startScroll = scrollWrapper.scrollTop();
    });
    
    scrollWrapper.bind('touchend', function() {
      var deltaTime = new Date().getTime() - startTime;
      var deltaScroll = Math.abs(startScroll - scrollWrapper.scrollTop());
      if (deltaScroll/deltaTime>0.25 
            || scrollWrapper.scrollTop()<0 
            || scrollWrapper.scrollTop()>scrollWrapper.height()) {
        // will cause momentum scroll, wait for 'scroll' event
        waitForScrollEvent = true;
      }
      else {
        onScrollCompleted(); // assume no momentum scroll was initiated
      }
      startTime = 0;
    });
    
    scrollWrapper.bind('scroll', function() {
      if (waitForScrollEvent) {
        onScrollCompleted();
      }
    });
    

    【讨论】:

    • 这太棒了!我一直在努力使内部 div 可滚动,并且通过启用动力,我所有的快照逻辑都消失了。您缺少几个逗号,并且未定义包装器变量。否则很好!
    • 很高兴您发现它很有用。感谢您指出错误。
    • 非常好。为它做一个演示。其他人快速检查结果可能很有用
    • 我不明白,你只听第一个滚动事件。当动量滚动发生时,它会一直发出滚动事件直到结束。正确答案如下。
    • 这是很久以前的事了。我相信问题的关键在于,在 Mobile Safari 上,动量滚动期间没有发出滚动事件。这就是上面的代码试图解决的问题。也许这已经改变了。
    【解决方案2】:

    在我的情况下,这非常有效:

    var timer;
    $(scrollWrapper).on('scroll',function(e){
        if(timer){
            clearTimeout(timer);
        }
        timer = setTimeout(function(){
           $(this).trigger('scrollFinished');
        }, 55)
    })
    
    
    
     $(scrollWrapper).on('scrollFinished',function(){
             // will be called when momentum scroll is finished
       })
    

    当滚动停止时发布'scrollfinished'事件。

    【讨论】:

    • 有趣的技术,对于某些特定的用例,它甚至比公认的答案更好(就像我的情况一样)。 +1
    • 非常简单的解决方案,不过我不得不将超时长度调整为更大的数字
    【解决方案3】:

    您还可以添加一个函数,该函数递归调用自身,直到滚动在元素内停止,然后从那里调用进一步的函数。

    isScrolling() {
      var scrollStart = <element>.scrollTop;
      setTimeout(function() {
        var scrollPos = <element>.scrollTop;
        if (scrollStart !== scrollPos) {
          this.isScrolling()
        } else {
          // Scrolling has stopped
        }
      }, 100)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多