33

I'm trying to prevent a mousewheel event captured by an element of the page to cause scrolling.

I expected false as last parameter to have the expected result, but using the mouse wheel over this "canvas" element still causes scrolling:

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

Outside of this "canvas" element, the scroll needs to happen. Inside, it must only trigger the .wheel() method. What am I doing wrong?

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
Jem
  • 6,226
  • 14
  • 56
  • 74

6 Answers6

46

You can do so by returning false at the end of your handler (OG).

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

Or using event.preventDefault()

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

Updated to use the wheel event as mousewheel deprecated for modern browser as pointed out in comments.

The question was about preventing scrolling not providing the right event so please check your browser support requirements to select the right event for your needs.

Updated a second time with a more modern approach option.

GillesC
  • 10,647
  • 3
  • 40
  • 55
  • 1
    +1: I had the exact same problem as this and a `return false;` worked – Neil Knight Apr 25 '12 at 09:49
  • I find it strange that false means that the event is handled. True would be more logical... – Aron Lorincz Aug 12 '15 at 07:48
  • 1
    @ÁronLőrincz You can think of the question being "should this event bubble up to further elements?", and the answer being false in this case. – Herman Schaaf Dec 12 '15 at 18:31
  • 5
    This doesn't seem to work anymore. @Zeta's answer is the only solution that worked directly in Chrome. In Firefox, I also had to change the (deprecated) `mousewheel` event to the `wheel` event. I'm adding this comment to save others from wasting time who may not see that answer. –  May 13 '16 at 14:45
  • `mousewheel` has been officially deprecated in favor of the `wheel` event: https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel – Matt Jensen Aug 23 '18 at 16:16
  • Maybe it's old or something, but event.preventDefault() as in answer below is the solution working for me. Returning false sounds more like a JQuery kind of way to do it. – Xavier Follet Oct 19 '20 at 12:14
  • @XavierFollet Answer dated 2012 so getting old yeah :) But no was not jQuery only, clearly worked for people back in the days and the answer is not using jQuery. Updated to include the modern approach either way. – GillesC Oct 19 '20 at 12:56
30

Have you tried event.preventDefault() to prevent the event's default behaviour?

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

Keep in mind that nowadays mouswheel is deprecated in favor of wheel, so you should use

this.canvas.addEventListener('wheel',function(event){
    mouseController.wheel(event);
    event.preventDefault();
}, false);
Zeta
  • 103,620
  • 13
  • 194
  • 236
3

Just adding, I know that canvas is only HTML5 so this is not needed, but just in case someone wants crossbrowser/oldbrowser compatibility, use this:

/* 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;
});
Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64
1

This kind of cancellation seems to be ignored in newer Chrome >18 Browsers (and perhaps other WebKit based Browsers). To exclusively capture the event you must directly change the onmousewheel method of the element.

this.canvas.onmousewheel = function(ev){
    //perform your own Event dispatching here
    return false;
};
Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
0

Finally, after trying everything else, this worked:

   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)
0

To prevent the wheel event, this worked for me in chrome -

this.canvas.addEventListener('wheel', function(event) {
    event.stopPropagation()
}, true);
Murtaza A
  • 31
  • 5