JavaScript:如何捕获鼠标滚轮事件并阻止页面滚动?

34
我想阻止页面元素捕获鼠标滚轮事件导致页面滚动。我期望使用false作为最后一个参数来达到预期的效果,但是在这个“画布”元素上使用鼠标滚轮仍然会导致页面滚动:
this.canvas.addEventListener('mousewheel', function(event) {
   mouseController.wheel(event);
}, false);

在这个“canvas”元素之外,滚动应该发生。在内部,它只能触发.wheel()方法。 我做错了什么?

6个回答

46

您可以通过在您的处理程序(OG)结尾返回false来实现此操作。

this.canvas.addEventListener('wheel',function(event){
    mouseController.wheel(event);
    return false; 
}, false);

或者使用 event.preventDefault()

this.canvas.addEventListener('wheel',function(event){
    mouseController.wheel(event);
    event.preventDefault();
}, false);

更新后使用wheel事件,因为在评论中指出mousewheel已经过时,不再适用于现代浏览器。

该问题是关于防止滚动而不是提供正确的事件,因此请检查您的浏览器支持要求以选择适合您需求的正确事件。

第二次更新使用了更现代化的方法选项。


1
+1:我遇到了与此完全相同的问题,使用“return false;”解决了问题。 - Neil Knight
我觉得奇怪的是,false表示事件已处理。True更合乎逻辑... - Aron Lorincz
1
@ÁronLőrincz 你可以把这个问题想象成“这个事件是否应该冒泡到更多的元素?”,而在这种情况下,答案是false。 - Herman Schaaf
5
似乎这个方法已经不再起作用了。@Zeta的答案是唯一一个在Chrome中直接起作用的解决方案。在Firefox中,我还需要将(已过时的)mousewheel事件更改为wheel事件。我添加了这个评论来帮助那些可能没有看到那个答案的人节省时间。 - user4275029
@XavierFollet 回答的日期是2012年,所以确实有点老了。但是它并不仅限于 jQuery,显然在那个时代为人们工作得很好,而且回答并没有使用 jQuery。不管哪种方式,都已经更新到包括现代方法了。 - GillesC
显示剩余2条评论

30

你尝试过使用event.preventDefault()来阻止事件的默认行为吗?

this.canvas.addEventListener('mousewheel',function(event){
    mouseController.wheel(event);
    event.preventDefault();
}, false);

请注意,现在推荐使用wheel,而mousewheel已被弃用,请相应更改代码。

this.canvas.addEventListener('wheel',function(event){
    mouseController.wheel(event);
    event.preventDefault();
}, false);

是的,就像这样 function(event){event.preventDefault(); mouseController.wheel(event)} - Jem
啊,我忘了返回false。感谢您的时间! - Jem

3

补充一下,我知道canvas只在HTML5中存在,所以这并不是必需的。但是,如果有人想要跨浏览器/旧浏览器兼容性,可以使用以下代码:

/* To attach the event: */
addEvent(el, ev, func) {
    if (el.addEventListener) {
        el.addEventListener(ev, func, false);
    } else if (el.attachEvent) {
        el.attachEvent("on" + ev, func);
    } else {
        el["on"+ev] = func; // Note that this line does not stack events. You must write you own stacker if you don't want overwrite the last event added of the same type. Btw, if you are going to have only one function for each event this is perfectly fine.
    }
}

/* To prevent the event: */
addEvent(this.canvas, "mousewheel", function(event) {
    if (!event) event = window.event;
    event.returnValue = false;
    if (event.preventDefault)event.preventDefault();
    return false;
});

1
这种取消似乎在新的Chrome >18浏览器(以及其他基于WebKit的浏览器)中被忽略了。要独占地捕获事件,您必须直接更改元素的onmousewheel方法。
this.canvas.onmousewheel = function(ev){
    //perform your own Event dispatching here
    return false;
};

0
为了防止滚轮事件,在Chrome中,这对我有用 -
this.canvas.addEventListener('wheel', function(event) {
    event.stopPropagation()
}, true);

0
最后,在尝试了其他一切方法之后,这个方法成功了:
   canvas.addEventListener('wheel', (event) => {
    
          // event.preventDefault(); Not Working
          // event.stopPropagation(); Not Working
          event.stopImmediatePropagation(); // WORKED!!
    
         console.log('Was default prevented? : ',event.defaultPrevented); // Says true 
    }, false)

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