Arless
Arless

Reputation: 462

Chrome - Javascript prevent default Ctrl + MouseWheel behavior

I'm trying to prevent the default Ctrl+MouseWheel zoom behavior in Chrome with JavaScript, for the other browsers I use preventDefault() and stopPropagation() in the callback function for mouse-wheel event and works perfect because the other browser always trigger a mouse-wheel event but Chrome does not.

Reading the question How to catch Zoom event with GWT and Chrome I found that Ctrl + MouseWheel can be caught as a resize event but after zooming the page so I can't prevent the behavior with this one.

Is there other event created before Ctrl+MouseWheel in Chrome or is a bug?

Upvotes: 13

Views: 9014

Answers (7)

Anand A Nair
Anand A Nair

Reputation: 21

For React JS

In my project, I added a ref for my component and then added event listener to the ref and set passive to false to disable the default Zoom in and out.

useEffect(() => {
const element = boxRef.current;
if (element) {
  element.addEventListener("wheel", handleWheel, {
    capture: true,
    passive: false,
  });
}

return () => {
  if (element) {
    element.removeEventListener("wheel", handleWheel);
  }
};
}, []);

My html is as follows:

<Box
    ref={boxRef}
    sx={{
      position: "relative",
      height: "100%",
      transform: `scale(${zoomValue / 100})`,
    }}
  ></Box>

My handleWheel funcion is:

const handleWheel = (event) => {
if (event.ctrlKey) {
  event.preventDefault();
  //control key is pressed
  if (event.deltaY > 0) {
    //scrolled down
    console.log("Scroll Down");
  } else {
    //scrolled up
    console.log("Scrolled Up");
  }
}
};

This works fine for me and I'm able to add my custom Zoom in and Zoom out.

Upvotes: 0

A5H1Q
A5H1Q

Reputation: 624

Found this fiddle on chromium bug tracker forum, seems now the issue has been fixed. Chromium now sends ctrl+wheel events to webkit first before using them for zooming. Rather than prevent scrolling for these events in EventHandler::handleWheel
event.preventDefault() should do the trick.

Upvotes: 1

mustafa kemal tuna
mustafa kemal tuna

Reputation: 1129

as a improving of @Vl4dimyr 's answer

document.getElementById('root').addEventListener('wheel', event => {
  if (event.ctrlKey) {
    event.preventDefault()
  }
}, true)

#root {
  position: absolute;
  top: 0;
  right: 0;
  /*-------------------important part----------------------*/
  /*bottom: 0;*/
  min-height:100vh; /*extendible cover for document*/
  /*-------------------------------------------------------*/
  left: 0;
  background: silver;
}

<div id="root">no zoom allowed</div>

Upvotes: -1

Vl4dimyr
Vl4dimyr

Reputation: 916

Trying to prevent zoom on window/document/body does not really work but wrapping the contents of the body with a div and preventing zoom on this works fine.

document.getElementById('root').addEventListener('wheel', event => {
  if (event.ctrlKey) {
    event.preventDefault()
  }
}, true)
#root {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: silver;
}
<div id="root">no zoom allowed</div>

Upvotes: 15

ImDaveead
ImDaveead

Reputation: 321

As of Chrome 76, the wheel event on window can be cancelled, but only if you register a passive event listener. From other answers and examples it seems like you can also cancel the event if it's on a DOM element such as a root <div>.

window.addEventListener('wheel', function(event) {
  event.preventDefault();
}, { passive: false });
body {
  font-family: sans-serif;
  font-size: 24px;
  background: #AAA;
}
<p>
  Inside of this page, you cannot zoom with the mouse wheel.
</p>

Upvotes: 4

Rob W
Rob W

Reputation: 349262

Unfortunately, it's impossible to intercept or block the CTRL + scrollwheel (zoom) event in Chrome.

This issue is being tracked at https://code.google.com/p/chromium/issues/detail?id=111059. Star the issue to get notified of (progress) updates.

Upvotes: 1

Dmitrii Stebliuk
Dmitrii Stebliuk

Reputation: 177

'wheel' event and preventDefault are working now. MDN.

Upvotes: 4

Related Questions