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

Zac*_*ach 332 javascript jquery

我正在寻找这样的效果:

$(window).scroll(function(event){
   if (/* magic code*/ ){
       // upscroll code
   } else {
      // downscroll code
   }
});
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Jos*_*ell 662

检查当前scrollTop与先前的比较scrollTop

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
Run Code Online (Sandbox Code Playgroud)

  • 有什么方法可以为此设置敏感度吗? (14认同)
  • 我在[this](http://codepen.io/josiahruddell/pen/piFfq)codepen上做了一个例子.也许我会用jQuery插件更新这个答案因为受欢迎程度. (7认同)
  • @TCHdvlp - 最糟糕的情况是**第一个**滚动事件会更新变量而**第二个**事件将是准确的(......只有在后退导航后才能进行上传).这可以通过在浏览器更新页面加载时的滚动位置后设置`var lastScrollTop = $(window).scrollTop()`来修复. (7认同)
  • 如果你回到上一页有这段代码,你试过这个吗?如果向下滚动页面,请说500PX.转到另一页然后返回初始页面.有些浏览器会保留滚动位置,并会将您带回页面.你有一个起始的'lastScrollTop`为0还是会正确初始化? (3认同)
  • 有关此内容的更新:请注意,某些浏览器(尤其是Windows 8上的IE 11)可以触发基于子像素的滚动事件(平滑滚动).但由于它将scrollTop报告为整数,因此您之前的滚动值可能与当前滚动值相同. (2认同)

cil*_*hex 163

您可以在不必跟踪上一个滚动顶部的情况下执行此操作,因为所有其他示例都需要:

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

我不是这方面的专家,所以请随意进一步研究它,但看起来当你使用时$(element).scroll,正在收听的事件是一个'滚动'事件.

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

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

  • 很好,但遗憾的是唯一的Firefox不支持它https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/mousewheel(在FF v15中测试).:C (13认同)
  • 如果我使用键盘滚动,这种方法将无法工作.对于像缩放这样的东西来说,这绝对是一个有趣的方法,但我不认为它解决了滚动方向问题. (13认同)
  • 很高兴你不需要旧的状态.然而,这种技术不适用于手机或平板电脑,因为它们没有鼠标滚轮! (11认同)
  • 这对我很有用:我需要检测滚动,即使页面本身实际上没有滚动,所以`scrollTop`没有更新.事实上,`$(window).scroll()`根本没有发射. (8认同)
  • $("html,body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll':function(e){// ...}); 适用于我检测所有浏览器滚动数据 (4认同)
  • 虽然到目前为止我一直使用这种技术,如果在没有鼠标滚轮的情况下滚动页面,它将无法工作.例如,通过滚动条上的鼠标.另外:Firefox仅支持`DOMmousescroll` (2认同)
  • +1因为这导致我正确的方向来解决我的问题:`event.wheelDeltaX`和`event.wheelDeltaY` (2认同)

Ski*_*ick 29

存储上一个滚动位置,然后查看新的滚动位置是否大于或小于该位置.

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

(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
Run Code Online (Sandbox Code Playgroud)


Che*_*mer 29

现有解决方案

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

解决方案1

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

解决方案2

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

解决方案3

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

多浏览器测试

我无法在Safari上测试它

铬42(赢7)

  • 解决方案1
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件
  • 解决2
    • Up:不工作
    • 下来:不工作
  • 解决方案3
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件

Firefox 37(Win 7)

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

IE 11(Win 8)

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

IE 10(Win 7)

  • 解决方案1
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件
  • 解决2
    • Up:不工作
    • 下来:不工作
  • 解决方案3
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件

IE 9(赢7)

  • 解决方案1
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件
  • 解决2
    • Up:不工作
    • 下来:不工作
  • 解决方案3
    • Up:每1个卷轴1个事件
    • 向下:每1个滚动1个事件

IE 8(Win 7)

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

综合解决方案

我检查了IE 11的副作用,IE 8来自if else声明.所以,我用if else if声明替换它如下.

从多浏览器测试中,我决定将解决方案3用于常见浏览器,将解决方案1用于firefox和IE 11.

我提到这个答案来检测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');
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)


sou*_*ous 12

我知道已经有一个公认的答案,但想发布我正在使用的内容,以防它可以帮助任何人.我得到了cliphex与鼠标滚轮事件相似的方向,但支持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
    }
});
Run Code Online (Sandbox Code Playgroud)


jhe*_*rax 8

滚动事件

滚动事件在FF奇怪的行为(这是开了很多次,因为平滑滚动),但它的工作原理.

注:滚动实际上事件被触发拖动滚动条时,使用光标键或鼠标滚轮.

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "35px"
});

//binds the "scroll" event
$(window).scroll(function (e) {
    var target = e.currentTarget,
        self = $(target),
        scrollTop = window.pageYOffset || target.scrollTop,
        lastScrollTop = self.data("lastScrollTop") || 0,
        scrollHeight = target.scrollHeight || document.body.scrollHeight,
        scrollText = "";

    if (scrollTop > lastScrollTop) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    $("#test").html(scrollText +
      "<br>innerHeight: " + self.innerHeight() +
      "<br>scrollHeight: " + scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>lastScrollTop: " + lastScrollTop);

    if (scrollHeight - scrollTop === self.innerHeight()) {
      console.log("? End of scroll");
    }

    //saves the current scrollTop
    self.data("lastScrollTop", scrollTop);
});
Run Code Online (Sandbox Code Playgroud)

轮子事件

您还可以看一下MDN,它会公开有关Wheel事件的精彩信息.

注意:仅在使用鼠标滚轮时才会触发滚轮事件; 光标键和拖动滚动条不会触发事件.

我阅读了文档和示例:在浏览器中收听此事件,
并在使用FF,IE,chrome,safari进行一些测试后,我最终得到了以下代码段:

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "15px"
});

//attach the "wheel" event if it is supported, otherwise "mousewheel" event is used
$("html").on(("onwheel" in document.createElement("div") ? "wheel" : "mousewheel"), function (e) {
    var evt = e.originalEvent || e;

    //this is what really matters
    var deltaY = evt.deltaY || (-1 / 40 * evt.wheelDelta), //wheel || mousewheel
        scrollTop = $(this).scrollTop() || $("body").scrollTop(), //fix safari
        scrollText = "";

    if (deltaY > 0) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    //console.log("Event: ", evt);
    $("#test").html(scrollText +
      "<br>clientHeight: " + this.clientHeight +
      "<br>scrollHeight: " + this.scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>deltaY: " + deltaY);
});
Run Code Online (Sandbox Code Playgroud)

  • 我有一个固定的面板视图,它禁用实际滚动条,所以我需要检测鼠标滚轮的方向.您的鼠标滚轮解决方案完美地跨浏览器工作,所以谢谢你! (2认同)

小智 8

如果您只想知道使用指针设备(鼠标或触控板)向上或向下滚动,可以使用事件的deltaY属性wheel.

$('.container').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
    $('.result').append('Scrolled down!<br>');
  } else {
    $('.result').append('Scrolled up!<br>');
  }
});
Run Code Online (Sandbox Code Playgroud)
.container {
  height: 200px;
  width: 400px;
  margin: 20px;
  border: 1px solid black;
  overflow-y: auto;
}
.content {
  height: 300px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="content">
    Scroll me!
  </div>
</div>

<div class="result">
  <p>Action:</p>
</div>
Run Code Online (Sandbox Code Playgroud)