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

我正在寻找这样的效果:

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

有任何想法吗?

检查当前的scrollTop vs之前的scrollTop

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

你可以做到这一点,而不必跟踪以前的滚动顶部,因为所有其他的例子需要:

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

我不是这方面的专家,所以可以随意研究它,但是当你使用$(element).scroll ,被监听的事件是一个'scroll'事件。

但是,如果您使用绑定专门监听mousewheel事件,则event参数的originalEvent属性将包含不同的信息。 部分信息是wheelDelta 。 如果是肯定的,你就把鼠标移动了。 如果是负值,则将鼠标滚轮向下移动。

我的猜测是,即使页面不滚动,鼠标滚轮转动时,鼠标mousewheel事件也会触发。 “滚动”事件可能不会被触发的情况。 如果你愿意的话,你可以调用callback函数底部的event.preventDefault()来防止滚动页面,这样就可以使用mousewheel事件来进行页面滚动之外的事情,比如某种缩放function。

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

这是避免任何全局variables的方法( 在这里可以find小提琴 ):

 (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 

现有的解决scheme

从这张贴和其他答案可能有3个解决scheme

解决scheme1

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

解决scheme2

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

解决scheme3

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

多浏览器testing

我无法在Safari上testing它

铬42(赢7)

  • 解决scheme1
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件
  • 解决2
    • 上:不工作
    • 下来:不工作
  • 解决scheme3
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件

Firefox 37(Win 7)

  • 解决scheme1
    • 最多:每个滚动20个事件
    • 向下:每1次滚动20个事件
  • 解决2
    • 上:不工作
    • 向下:每1次滚动1个事件
  • 解决scheme3
    • 上:不工作
    • 下来:不工作

IE 11(Win 8)

  • 解决scheme1
    • 上行:每滚动10个事件(副作用:最后发生下滚动)
    • 向下:每滚动10个事件
  • 解决2
    • 上:不工作
    • 下来:不工作
  • 解决scheme3
    • 上:不工作
    • 向下:每1次滚动1个事件

IE 10(Win 7)

  • 解决scheme1
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件
  • 解决2
    • 上:不工作
    • 下来:不工作
  • 解决scheme3
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件

IE 9(Win 7)

  • 解决scheme1
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件
  • 解决2
    • 上:不工作
    • 下来:不工作
  • 解决scheme3
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件

IE 8(Win 7)

  • 解决scheme1
    • 最多:每次滚动2个事件(副作用:最后发生向下滚动)
    • 向下:每滚动2〜4个事件
  • 解决2
    • 上:不工作
    • 下来:不工作
  • 解决scheme3
    • 上一次:每滚动1个事件
    • 向下:每1次滚动1个事件

综合解决scheme

我检查了从IE 11和IE 8的副作用来自if else语句。 所以,我把它replace, if else if语句如下。

从多浏览器testing中,我决定使用常见浏览器的解决scheme3和Firefox 11和IE 11的解决scheme1

我提到这个答案来检测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'); } }); } 

我知道已经有一个被接受的答案,但是想要发布我正在使用的东西,以便能够帮助任何人。 我得到了与鼠标滚轮事件cliphex一样的方向,但支持Firefox。 这样做是有用的,如果你正在做locking滚动和无法获得当前滚动顶部的东西。

在这里看到一个真人版。

 $(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 } }); 

滚动事件

滚动事件在FF中performance奇怪(由于平滑滚动,它被激发很多次),但是它起作用。

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

 //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); }); 

车轮事件

你也可以看看MDN,它揭示了关于车轮事件的一个很好的信息

注意:轮子事件只有在使用鼠标滚轮时才会触发 光标键和拖动滚动条不会触发事件。

我阅读文档和示例: 通过浏览器收听此事件
经过一些FF,IE浏览器,Chrome浏览器,Safari浏览器的testing后,我最终得到了这个片段:

 //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); }); 

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

 $('.container').on('wheel', function(event) { if (event.originalEvent.deltaY > 0) { $('.result').append('Scrolled down!<br>'); } else { $('.result').append('Scrolled up!<br>'); } }); 
 .container { height: 200px; width: 400px; margin: 20px; border: 1px solid black; overflow-y: auto; } .content { height: 300px; } 
 <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> 
 var tempScrollTop, currentScrollTop = 0; $(window).scroll(function(){ currentScrollTop = $("#div").scrollTop(); if (tempScrollTop > currentScrollTop ) { // upscroll code } else if (tempScrollTop < currentScrollTop ){ // downscroll code } tempScrollTop = currentScrollTop; } 

或使用鼠标滚轮扩展 ,请看这里 。

要忽略页面顶部和底部的任何捕捉/动量/反弹,以下是Josiah接受的答案的修改版本:

 var prevScrollTop = 0; $(window).scroll(function(event){ var scrollTop = $(this).scrollTop(); if ( scrollTop < 0 ) { scrollTop = 0; } if ( scrollTop > $('body').height() - $(window).height() ) { scrollTop = $('body').height() - $(window).height(); } if (scrollTop >= prevScrollTop && scrollTop) { // scrolling down } else { // scrolling up } prevScrollTop = scrollTop; }); 

你可以确定mousewhell的方向。

 $(window).on('mousewheel DOMMouseScroll', function (e) { var delta = e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -e.originalEvent.detail; if (delta >= 0) { console.log('scroll up'); } else { console.log('scroll down'); } }); 

我在这里看到很多好的答案,但似乎有些人有跨浏览器的问题,所以这是我的修复。

我已经成功地使用这个来检测方向在FF,IE和Chrome …我没有在Safari浏览器中testing,因为我通常使用Windows。

 $("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': function(e) { if (e.target.id == 'el') return; e.preventDefault(); e.stopPropagation(); //Determine Direction if (e.originalEvent.wheelDelta && e.originalEvent.wheelDelta >= 0) { //Up alert("up"); } else if (e.originalEvent.detail && e.originalEvent.detail <= 0) { //Up alert("up"); } else { //Down alert("down"); } } }); 

请记住,我也使用这个来停止任何滚动,所以如果你想滚动仍然发生,你必须删除e.preventDefault(); e.stopPropagation(); e.preventDefault(); e.stopPropagation();

使用此来查找滚动方向。 这只是find垂直滚动的方向。 支持所有的跨浏览器。

  var scrollableElement = document.getElementById('scrollableElement'); scrollableElement.addEventListener('wheel', findScrollDirectionOtherBrowsers); function findScrollDirectionOtherBrowsers(event){ var delta; if (event.wheelDelta){ delta = event.wheelDelta; }else{ delta = -1 * event.deltaY; } if (delta < 0){ console.log("DOWN"); }else if (delta > 0){ console.log("UP"); } } 

在滚动的元素的.data ()中增加一个增量,您将能够testing滚动到达顶部的次数。

对于那些有弹性滚动的问题,请使用这个答案

如何检测滚动方向

在元素的.data()中,您可以存储JSON并testing值以启动事件

 { top : 1, first_top_event: function(){ ...}, second_top_event: function(){ ...}, third_top_event: function(){ ...}, scroll_down_event1: function(){ ...}, scroll_down_event2: function(){ ...} } 

这可能有帮助

 <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <meta charset=utf-8 /> <title>JS Bin</title> <script type='text/javascript'> $(function(){ //Keep track of last scroll var lastScroll = 0; $(window).scroll(function(event){ //Sets the current scroll position var st = $(this).scrollTop(); //Determines up-or-down scrolling if (st > lastScroll){ //alert("DOWN"); $('#bg').text('DOWN') } else { //alert("UP"); $('#bg').text('UP') } //Updates scroll position lastScroll = st; }); }); </script> </head> <body> <h1 id="bg">Scroll Here</h1> </body> </html> 

当用户从页面的顶部滚动并返回到顶部时,这是简单而容易的检测。

 $(window).scroll(function() { if($(window).scrollTop() > 0) { // User has scrolled } else { // User at top of page } }); 

这是在用户结束滚动时检测方向的最佳解决scheme。

 var currentScrollTop = 0 ; $(window).bind('scroll', function () { scrollTop = $(this).scrollTop(); clearTimeout($.data(this, 'scrollTimer')); $.data(this, 'scrollTimer', setTimeout(function() { if(scrollTop > currentScrollTop){ // downscroll code $('.mfb-component--bl').addClass('mfbHide'); }else{ // upscroll code $('.mfb-component--bl').removeClass('mfbHide'); } currentScrollTop = scrollTop; }, 250)); }); 

保持超级简单:

jQuery事件监听器方式:

 $(window).on('wheel', function(){ whichDirection(event); }); 

香草JavaScript事件监听器方式:

 if(window.addEventListener){ addEventListener('wheel', whichDirection, false); } else if (window.attachEvent) { attachEvent('wheel', whichDirection, false); } 

function保持不变:

 function whichDirection(event){ console.log(event + ' WheelEvent has all kinds of good stuff to work with'); var scrollDirection = event.deltaY; if(scrollDirection === 1){ console.log('meet me at the club, going down', scrollDirection); } else if(scrollDirection === -1) { console.log('Going up, on a tuesday', scrollDirection); } } 

我在这里写了一篇更深入的文章

您可以同时使用滚动和鼠标滚轮选项来追踪上下移动。

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

你也可以用(窗口)replace“body”。

你应该试试这个

 var scrl $(window).scroll(function(){ if($(window).scrollTop() < scrl){ //some code while previous scroll }else{ if($(window).scrollTop() > 200){ //scroll while downward }else{//scroll while downward after some specific height } } scrl = $(window).scrollTop(); });