首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >检测滚动事件是否由用户创建

检测滚动事件是否由用户创建
EN

Stack Overflow用户
提问于 2011-08-12 13:23:27
回答 10查看 50.7K关注 0票数 95

是否可以判断滚动事件是由浏览器还是由用户完成的?具体地说,当使用后退按钮时,浏览器可能会跳到最后一个已知的滚动位置。如果我绑定到scroll事件,我如何判断这是由用户还是浏览器引起的?

代码语言:javascript
复制
$(document).scroll( function(){ 
    //who did this?!
});

我看到了三种导致浏览器滚动的情况。

  1. 用户执行某些操作。例如,使用鼠标滚轮、箭头键、page up/down键、home/end键、单击滚动条或拖动其拇指。
  2. 浏览器会自动滚动。例如,当使用浏览器中的后退按钮时,它会跳转到最后一个已知的滚动位置automatically.
  3. Javascript scrolls。例如,element.scrollTo(x,y).
EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2011-08-27 04:12:38

不幸的是,没有直接的方式来说明这一点。

我想说,如果你可以redesign你的应用程序,让它不依赖于这种类型的流程,那就去做吧。

如果没有,我能想到的一个解决办法是跟踪用户发起的滚动,并检查滚动是由浏览器还是由用户触发的。

下面是我放在一起的一个例子,它做得很好(除了jQuery历史记录有问题的浏览器)。

你需要在本地运行它才能对其进行完整的测试(jsbin/jsbin不是很合适,因为它们iFrame了内容)。

下面是我验证的测试用例

后退/前进页面加载-使用鼠标/键盘时false

  • Scroll为-链接上的false
  • Click变为false;

以跳转到页面底部- userScroll变为false

  • Click Back/Forward - userScroll变为false

代码语言:javascript
复制
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script> 
    <script type="text/javascript" src="https://raw.github.com/tkyk/jquery-history-plugin/master/jquery.history.js"></script> 
</head> 
<body> 
    <span> hello there </span><br/> 
    <a href="#bottom"> click here to go down </a> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <a name="bottom"> just sitting </a> 
</body> 
<script type="text/javascript"> 

var userScroll = false;     

function mouseEvent(e) { 
    userScroll = true; 
} 


$(function() { 

    // reset flag on back/forward 
    $.history.init(function(hash){ 
        userScroll = false; 
    }); 

    $(document).keydown(function(e) { 
        if(e.which == 33        // page up 
           || e.which == 34     // page dn 
           || e.which == 32     // spacebar
           || e.which == 38     // up 
           || e.which == 40     // down 
           || (e.ctrlKey && e.which == 36)     // ctrl + home 
           || (e.ctrlKey && e.which == 35)     // ctrl + end 
          ) { 
            userScroll = true; 
        } 
    }); 

    // detect user scroll through mouse
    // Mozilla/Webkit 
    if(window.addEventListener) {
        document.addEventListener('DOMMouseScroll', mouseEvent, false); 
    }

    //for IE/OPERA etc 
    document.onmousewheel = mouseEvent; 


    // to reset flag when named anchors are clicked
    $('a[href*=#]').click(function() { 
        userScroll = false;
    }); 

      // detect browser/user scroll
    $(document).scroll( function(){  
        console.log('Scroll initiated by ' + (userScroll == true ? "user" : "browser"));
    });
}); 
</script> 
</html>

备注:

  • 当用户用鼠标拖动滚动条时,它不会跟踪滚动。还可以添加更多代码,我将这些代码作为you.
  • event.keyCodes的练习,这些代码可能因操作系统而异,因此您可能需要更改该appropriately.

希望这能有所帮助!

票数 33
EN

Stack Overflow用户

发布于 2017-11-29 20:41:24

与试图捕获所有用户事件相比,相反的做法要容易得多,只处理编程事件,而忽略这些事件。

例如,这种代码可以工作:

代码语言:javascript
复制
// Element that needs to be scrolled
var myElement = document.getElementById('my-container');

// Flag to tell if the change was programmatic or by the user
var ignoreNextScrollEvent = false;

function setScrollTop(scrollTop) {
    ignoreNextScrollEvent = true;
    myElement.scrollTop = scrollTop
}

myElement.addEventListener('scroll', function() {
    if (ignoreNextScrollEvent) {
        // Ignore this event because it was done programmatically
        ignoreNextScrollEvent = false;
        return;
    }

    // Process user-initiated event here
});

然后,当您调用setScrollTop()时,scroll事件将被忽略,而如果用户使用鼠标、键盘或任何其他方式滚动,则将处理该事件。

票数 10
EN

Stack Overflow用户

发布于 2011-08-25 16:04:13

据我所知,这是不可能的(没有任何工作),无论何时滚动事件已发出“用户”或其他方式。

您可以尝试(正如其他人提到的)捕获鼠标滚轮事件,然后可能尝试捕获任何可以触发滚动(箭头、空格等)的键上的按键事件。同时检查当前聚焦的元素,因为您不能在输入字段时使用箭头键进行滚动。一般来说,这将是复杂和混乱的脚本。

根据你正在处理的情况,我猜你可以“还原逻辑”,而不是检测用户发出的滚动事件,只需连接到任何以编程方式制作的滚动中,并将由您的代码的任何滚动事件视为用户所做的。就像我说的,这取决于情况,以及你想要实现的目标。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7035896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档