在jQuery中如何获取鼠标滚轮事件?

153

在jQuery中是否有一种方法可以获取鼠标滚轮事件(不是scroll事件)?


2
快速搜索找到了这个插件,可能会有所帮助。 - Jerad Rose
这个解决方案对我有效:https://dev59.com/7Ww05IYBdhLWcg3wkivX - Bertie
@thejh 在此发布了一个关于DOM3事件的新回答:https://dev59.com/J2sy5IYBdhLWcg3w-i_h#24707712 - Sergio
可能是 jQuery scroll() detect when user stops scrolling 的重复问题。 - divy3993
仅作说明。如果您只想检测输入内容的更改,并且它无法通过鼠标滚轮检测更改,请尝试使用 $(el).on('input',... - rybo111
15个回答

222
​$(document).ready(function(){
    $('#foo').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta /120 > 0) {
            console.log('scrolling up !');
        }
        else{
            console.log('scrolling down !');
        }
    });
});

53
DOMMouseScroll 事件在Firefox中使用,因此您需要同时监听 .bind('DOMMouseScroll mousewheel') { 两个事件。 - e382df99a7950919789725ceeec126
10
在Firefox23中,e.originalEvent.wheelDelta未定义。 - hofnarwillie
27
不需要除以120,这是浪费CPU的无用操作。 - venimus
6
一定是最佳答案。 - user2869113
2
但是,无论如何,为什么你想要将它除以120呢?那个常数是什么?(正如venimus所指出的那样,你不必这样做。) - mshthn
显示剩余6条评论

153

同时绑定 mousewheelDOMMouseScroll 对我来说效果非常好:

$(window).bind('mousewheel DOMMouseScroll', function(event){
    if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
        // scroll up
    }
    else {
        // scroll down
    }
});

这种方法在IE9+,Chrome 33和Firefox 27中可用。


编辑 - 2016年3月

我决定重新访问这个问题,因为已经有一段时间了。 MDN关于滚动事件的页面有一个很好的检索滚动位置的方法,它利用了requestAnimationFrame,这比我的先前的检测方法要好得多。 我修改了他们的代码,以提供更好的兼容性,还包括滚动方向和位置:

(function() {
  var supportOffset = window.pageYOffset !== undefined,
    lastKnownPos = 0,
    ticking = false,
    scrollDir,
    currYPos;

  function doSomething(scrollPos, scrollDir) {
    // Your code goes here...
    console.log('scroll pos: ' + scrollPos + ' | scroll dir: ' + scrollDir);
  }

  window.addEventListener('wheel', function(e) {
    currYPos = supportOffset ? window.pageYOffset : document.body.scrollTop;
    scrollDir = lastKnownPos > currYPos ? 'up' : 'down';
    lastKnownPos = currYPos;

    if (!ticking) {
      window.requestAnimationFrame(function() {
        doSomething(lastKnownPos, scrollDir);
        ticking = false;
      });
    }
    ticking = true;
  });
})();

Vanilla JS 滚动跟踪 @blindside85 CodePen

该代码目前在 Chrome v50、Firefox v44、Safari v9 和 IE9+ 中可用

参考资料:


1
我找到了一种方法来实现这个:https://dev59.com/HYDba4cB1Zd3GeqPAB9S - invot
@JesseDupuy 如果要使用计时器,请确保您(或是任何阅读这条信息的人)为不同的“线程”使用队列系统。如果堆叠计时器,会对渲染产生可怕的影响。我已经为这种情况编写了一个脚本,并在Github上分享:https://github.com/erik-landvall/animator - superhero
1
谢谢你的更新。你能把你的代码复制到回答里吗?毕竟不知道Codepen将来会不会出问题。(这种情况以前也发生过。) - JDB
2
@JesseDupuy,我会点赞这个答案,但是你更新的版本如果文档适合视图(“width: 100vh; height: 100vh”)或者有“overflow: hidden;”就无法工作。 "window.addEventListener('scroll', callback)" 不是正确的回答,而是 "window.addEventListener('mousewheel', callback)"。 - Daniel
很棒的答案。正如@Daniel所指出的那样,“overflow: hidden”在新版本中不起作用,但原始版本与之配合非常好。我需要它用于使用鼠标滚动缩放的Web应用程序,现在它完美地运行着。 - kevinmicke
显示剩余5条评论

72

截至2017年,您只需编写以下内容:

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

  // deltaY obviously records vertical scroll, deltaX and deltaZ exist too.
  // this condition makes sure it's vertical scrolling that happened
  if(event.originalEvent.deltaY !== 0){

    if(event.originalEvent.deltaY < 0){
      // wheeled up
    }
    else {
      // wheeled down
    }
  }
});

适用于当前的Firefox 51,Chrome 56和IE9 +


这个答案比其他所有答案都更好! - VDWWD
1
当水平滚动时,“event.originalEvent.deltaY”可能为0(我在笔记本电脑上尝试过),因此您可能希望使用if x<0else ifx>0 - ajax333221

49

有一个插件,可以检测鼠标在区域内的上下滚动和速度。


40
插件?来吧,看看下面的答案,你可以不使用插件完成它。 - user2869113

40

20
我尝试了这些并发现:“wheel”在Firefox和IE中可用,但在Chrome中不行。“mousewheel”在Chrome和IE中可用,但在Firefox中不行。“DOMMouseScroll”仅在Firefox中可用。 - Curtis Yallop
1
哇,这节省了我很多时间。谢谢! - gustavohenke
5
看起来Chrome在2013年8月加入了对"wheel"的支持:https://code.google.com/p/chromium/issues/detail?id=227454 - rstackhouse
2
Safari 仍不支持滚轮事件。 - Thayne
正如您的文档所述,“wheel”事件在“Edge”上受支持,而不是在“IE”上受支持,这是两码事。CanIuse - Alex

16

这对我起作用了:)

 //Firefox
 $('#elem').bind('DOMMouseScroll', function(e){
     if(e.originalEvent.detail > 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

 //IE, Opera, Safari
 $('#elem').bind('mousewheel', function(e){
     if(e.originalEvent.wheelDelta < 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

来自stackoverflow


14

这里是一个基本解决方案。如果传递给函数的事件是 event.originalEvent,它可以在jQuery中使用,因为jQuery将其作为jQuery事件的属性提供。或者如果在callback函数中,我们在第一行之前添加:event = event.originalEvent;

此代码规范化滚轮速度/量,并对典型鼠标中的向前滚动具有正值,并且对于向后鼠标滚轮运动具有负值。

演示:http://jsfiddle.net/BXhzD/

var wheel = document.getElementById('wheel');

function report(ammout) {
    wheel.innerHTML = 'wheel ammout: ' + ammout;
}

function callback(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    report(normalized);
}

var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
window.addEventListener(event, callback);

还有一个 jQuery 插件,它的代码更冗长并且提供了额外的语法糖:https://github.com/brandonaaron/jquery-mousewheel


8
这在每个IE,Firefox和Chrome的最新版本中都有效。
$(document).ready(function(){
        $('#whole').bind('DOMMouseScroll mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
                alert("up");
            }
            else{
                alert("down");
            }
        });
    });

5

今天我遇到了这个问题,发现以下代码对我非常有效

$('#content').on('mousewheel', function(event) {
    //console.log(event.deltaX, event.deltaY, event.deltaFactor);
    if(event.deltaY > 0) {
      console.log('scroll up');
    } else {
      console.log('scroll down');
    }
});

4
请使用以下代码:

使用此代码

 knob.bind('mousewheel', function(e){  
 if(e.originalEvent.wheelDelta < 0) {
    moveKnob('down');
  } else {
    moveKnob('up');
 }
  return false;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接