如何确定 jQuery 滚动事件的方向?

IT技术 javascript jquery
2021-02-02 07:44:40

我正在寻找这种效果的东西:

$(window).scroll(function(event){
   if (/* magic code*/ ){
       // upscroll code
   } else {
      // downscroll code
   }
});

有任何想法吗?

6个回答

检查当前scrollTop与以前scrollTop

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
@TCHdvlp - 在最坏的情况下,第一个滚动事件将更新变量,而第二个事件将是准确的(.. 只有在返回导航后向上滚动才重要)。这可以通过var lastScrollTop = $(window).scrollTop()在浏览器更新页面加载滚动位置后进行设置来解决
2021-03-20 07:44:40
有什么办法可以对此设置敏感度吗?
2021-04-02 07:44:40
如果您返回具有此代码的上一页,您是否尝试过此操作?如果您向下滚动页面,请说 500PX。转到另一个页面,然后返回到初始页面。某些浏览器会保持滚动位置并将您带回页面。你会从lastScrollTop0开始还是会正确初始化?
2021-04-02 07:44:40
对此的更新:请注意某些浏览器,特别是 Windows 8 上的 IE 11,可以触发基于子像素的滚动事件(平滑滚动)。但是因为它将 scrollTop 报告为一个整数,所以您之前的滚动值可能与当前值相同。
2021-04-02 07:44:40
我在这个codepen做了一个例子由于流行,我可能会使用 jQuery 插件更新此答案。
2021-04-06 07:44:40

您无需跟踪前一个滚动顶部即可完成此操作,因为所有其他示例都需要:

$(window).bind('mousewheel', function(event) {
    if (event.originalEvent.wheelDelta >= 0) {
        console.log('Scroll up');
    }
    else {
        console.log('Scroll down');
    }
});

我不是这方面的专家,因此请随意进一步研究,但似乎当您使用 时$(element).scroll,正在侦听的事件是“滚动”事件。

但是,如果您专门mousewheel使用 bind侦听事件,则originalEvent回调的 event 参数属性包含不同的信息。该信息的一部分是wheelDelta. 如果是肯定的,则您将鼠标滚轮向上移动。如果它是负数,则您将鼠标滚轮向下移动。

我的猜测是mousewheel,即使页面不滚动,鼠标滚轮转动时也会触发事件;可能不会触发“滚动”事件的情况。如果需要,您可以event.preventDefault()在回调的底部调用以防止页面滚动,这样您就可以将 mousewheel 事件用于页面滚动以外的其他内容,例如某种类型的缩放功能。

如果我用键盘滚动,这种方法将不起作用。对于缩放之类的东西来说,这绝对是一种有趣的方法,但我认为它不能解决滚动方向问题。
2021-03-10 07:44:40
这对我很有用:我需要检测滚动,即使页面本身实际上并没有滚动,所以scrollTop没有更新。事实上,$(window).scroll()根本没有火。
2021-03-15 07:44:40
很高兴您不需要旧状态。然而,这种技术不适用于手机或平板电脑,因为它们没有鼠标滚轮!
2021-03-16 07:44:40
$("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': function(e) { //... }); 适用于我检测所有浏览器滚动数据
2021-03-17 07:44:40
很好,但遗憾的是,唯一的 Firefox 不支持它developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/...(在 FF v15 中测试)。:C
2021-04-08 07:44:40

存储之前的滚动位置,然后查看新的滚动位置是大于还是小于该位置。

这是一种避免任何全局变量的方法(此处提供小提琴):

(function () {
    var previousScroll = 0;

    $(window).scroll(function(){
       var currentScroll = $(this).scrollTop();
       if (currentScroll > previousScroll){
           alert('down');
       } else {
          alert('up');
       }
       previousScroll = currentScroll;
    });
}()); //run this anonymous function immediately

现有解决方案

这个帖子和其他答案可能有3 个解决方案

方案一

    var lastScrollTop = 0;
    $(window).on('scroll', function() {
        st = $(this).scrollTop();
        if(st < lastScrollTop) {
            console.log('up 1');
        }
        else {
            console.log('down 1');
        }
        lastScrollTop = st;
    });

解决方案2

    $('body').on('DOMMouseScroll', function(e){
        if(e.originalEvent.detail < 0) {
            console.log('up 2');
        }
        else {
            console.log('down 2');
        }
    });

解决方案3

    $('body').on('mousewheel', function(e){
        if(e.originalEvent.wheelDelta > 0) {
            console.log('up 3');
        }
        else {
            console.log('down 3');
        }
    });

多浏览器测试

我无法在 Safari 上对其进行测试

铬 42(赢 7)

  • 方案一
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件
  • 解决方案2
    • 上:不工作
    • 向下:不工作
  • 解决方案3
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件

火狐 37 (Win 7)

  • 方案一
    • 向上:每 1 个滚动 20 个事件
    • 向下:每 1 个滚动 20 个事件
  • 解决方案2
    • 上:不工作
    • 向下:每 1 个滚动 1 个事件
  • 解决方案3
    • 上:不工作
    • 向下:不工作

IE 11(赢8)

  • 方案一
    • 向上:每 1 个滚动 10 个事件(副作用:最后发生向下滚动)
    • 向下:每 1 个滚动 10 个事件
  • 解决方案2
    • 上:不工作
    • 向下:不工作
  • 解决方案3
    • 上:不工作
    • 向下:每 1 个滚动 1 个事件

IE 10(赢 7)

  • 方案一
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件
  • 解决方案2
    • 上:不工作
    • 向下:不工作
  • 解决方案3
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件

IE 9(赢 7)

  • 方案一
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件
  • 解决方案2
    • 上:不工作
    • 向下:不工作
  • 解决方案3
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件

IE 8(赢 7)

  • 方案一
    • 向上:每 1 次滚动 2 个事件(副作用:最后发生向下滚动)
    • 向下:每 1 个滚动 2~4 个事件
  • 解决方案2
    • 上:不工作
    • 向下:不工作
  • 解决方案3
    • 向上:每 1 个滚动 1 个事件
    • 向下:每 1 个滚动 1 个事件

组合解决方案

我检查了 IE 11 和 IE 8 的副作用来自if else声明。因此,我将其替换if else if为以下语句。

从多浏览器测试来看,我决定对常用浏览器使用解决方案3对firefox和IE 11使用解决方案1

我参考了这个答案来检测 IE 11。

    // Detect IE version
    var iev=0;
    var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var rv=navigator.userAgent.indexOf("rv:11.0");

    if (ieold) iev=new Number(RegExp.$1);
    if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10;
    if (trident&&rv!=-1) iev=11;

    // Firefox or IE 11
    if(typeof InstallTrigger !== 'undefined' || iev == 11) {
        var lastScrollTop = 0;
        $(window).on('scroll', function() {
            st = $(this).scrollTop();
            if(st < lastScrollTop) {
                console.log('Up');
            }
            else if(st > lastScrollTop) {
                console.log('Down');
            }
            lastScrollTop = st;
        });
    }
    // Other browsers
    else {
        $('body').on('mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0) {
                console.log('Up');
            }
            else if(e.originalEvent.wheelDelta < 0) {
                console.log('Down');
            }
        });
    }
如果有人可以添加 的结果Safari browser,则有助于补充解决方案。
2021-03-13 07:44:40
如果设计是固定布局设计,则不起作用。如果您想检测静态无滚动网站上的滚动方向,Firefox 和 IE11 将不起作用
2021-03-22 07:44:40
oop!我发现Mobile Chrome和Android默认浏览器只被解决方案1覆盖。所以最好同时使用解决方案1和3来覆盖各种浏览器。
2021-04-03 07:44:40
我发现当我使用它时,它使用 chrome 中的“其他浏览器”,当您希望通过鼠标滚轮和滚动条检测滚动时,这并没有多大用处。.scroll 将检测 chrome 中的两种类型的滚动。
2021-04-07 07:44:40

我知道已经有一个被接受的答案,但想发布我正在使用的内容,以防它可以帮助任何人。我得到了类似cliphexmousewheel 事件的方向,但支持 Firefox。如果您正在执行诸如锁定滚动之类的操作并且无法获取当前滚动顶部,则这样做很有用。

在此处查看实时版本

$(window).on('mousewheel DOMMouseScroll', function (e) {

    var direction = (function () {

        var delta = (e.type === 'DOMMouseScroll' ?
                     e.originalEvent.detail * -40 :
                     e.originalEvent.wheelDelta);

        return delta > 0 ? 0 : 1;
    }());

    if(direction === 1) {
       // scroll down
    }
    if(direction === 0) {
       // scroll up
    }
});
@EtienneMartin 上面的代码依赖于 jQuery,如果那是导致错误的原因。请参阅随附的小提琴以查看它的工作原理。
2021-03-12 07:44:40