区分用户启动的滚动与页面加载时发生的浏览器启动的滚动

时间:2011-11-19 22:14:33

标签: javascript jquery scroll

我想知道用户何时首次在我的页面上滚动,这与您重新加载页面时自动发生的浏览器启动的滚动不同。

  • 如果我尝试捕获窗口的初始滚动位置,然后注册一个onscroll处理程序告诉我滚动位置已经改变,我不会太过分:浏览器启动的滚动发生在文档准备好之后(jQuery的定义) ),所以window.pageYOffset在doc就绪时始终为0,即使浏览器正好向下跳过一百个像素。

  • 如果我尝试检查onscroll事件,似乎没有任何东西让我区分用户启动的事件对象和浏览器启动的事件对象。这两个事件具有相同的属性。

  • 我正在寻找比这里建议更强大的东西:How to distinguish scrolling by mouse from scrolling programmatically in JavaScript?

...谢谢

3 个答案:

答案 0 :(得分:0)

这很难看,但可能最好的方法是通过计时。我注意到在Chrome上,pageYOffset的变化发生在window.onload的1毫秒内,而在Firefox上,它发生在dom加载的1毫秒内。 (没有测试IE,但很可能是其中一个工作)例如我将它添加到页面底部:

  <script>
    window.onload = function () {
      var first = window.pageYOffset;

      setTimeout(function () {
          second = window.pageYOffset;
          alert("first: " + first + ", second:" + second)
        }, 1);
    };
   </script>

一个chrome,“first”为0,“second”是一个大数字,刷新滚动页面时。在firefox上,只有在关闭正文标记之前添加以下内容时才会出现这种情况(应该与jquery的document.ready相同)。

  <script>
      var first = window.pageYOffset;

      setTimeout(function () {
          second = window.pageYOffset;
          alert("first: " + first + ", second:" + second)
        }, 1);
   </script>

我认为您可以使用这种技术可靠地检测到“浏览器刷新启动”滚动,但很明显,它不是我称之为漂亮的解决方案,它可能会破坏未来的浏览器版本。

答案 1 :(得分:0)

我在主页上使用类似的技术进行滚动行为,而不是最优雅,但效果很好:

<html>
<head></head>
<body>
    <div style="height:500px;line-height:500px">
        <a id="bm" href="#bm">bookmarked</a>
    </div>
<script>
    (function(){

        var scrollingCanStart = false;

        //the user interact with the page
        window.onmouseover = window.onkeydown = function(e){
            scrollingCanStart = true;
        };

        //onscroll action
        window.onscroll = function(e){
            if(!scrollingCanStart){
                return;
            }
            console.log('manual scroll');
        };

    })();
</script>
</body>
</html>

答案 2 :(得分:0)

我正在解决同样的任务,并愿意分享我的方法。

我的假设:

  1. 用户的滚动始终预先包含“ wheel ”等事件, '另一个用户的滚动'等等
  2. 所有活动都有 timeStamp
  3. 我已选择 rxjs 库进行实施

    // this stream will contain last User's scroll
    var last_scroll = new Rx.Subject();
    
    var start = rx.Observable.merge(
         Rx.Observable.fromEvent(element, 'wheel'),
         last_scroll
    )
    .map(function (e) { return e.timeStamp; });
    
    
    Rx.Observable.fromEvent(element, 'scroll')
    .withLatestFrom(start, function (scroll, start) {
        return {scroll: scroll, start: start};
    })
    .filter(function (o) {
        return Math.abs(o.scroll.timeStamp - o.start) <= 500;
    })
    .map(function (o) {
        return o.scroll;
    })
    .do(function (ev) {
        last_scroll.onNext(ev);
    })
    .subscribe(function (ev) {
    
        // here we have scroll event initiated by user
    });
    

    请随时改进此代码并分享您的想法。快乐的编码!