Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wheel event PreventDefault does not cancel wheel event

I would like to get one event only per scroll event

I try this code but it produces "wheel" as many times the wheel event is triggered. Any help? Thank you

window.addEventListener("wheel",
    (e)=> {
        console.log("wheel");
        e.preventDefault();
    },
    {passive:false}
    );

Use case (edit) I want to allow scrolling from page to page only - with an animation while scrolling. As soon I detect the onwheel event, I would like to stop it before the animation finishes, otherwise the previous onwheel continues to fire and it is seen as new event, so going to the next of the targeted page

My conclusion : It is not possible to cancel wheel events. In order to identify a new user wheel action while wheeling events (from a former user action) are on going, we need to calculate the speed/acceleration of such events

like image 968
tit Avatar asked Sep 23 '19 11:09

tit


People also ask

Does preventDefault stop bubbling?

preventDefault() Prevents the browsers default behaviour (such as opening a link), but does not stop the event from bubbling up the DOM.

What does event preventDefault () do?

preventDefault() The preventDefault() method of the Event interface tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.

What is the opposite of event preventDefault ()?

There is no opposite method of event. preventDefault() to understand why you first have to look into what event. preventDefault() does when you call it. Underneath the hood, the functionality for preventDefault is essentially calling a return false which halts any further execution.

What's the difference between event preventDefault () and event stopPropagation ()?

The event. preventDefault() will not allow the user to leave the page and open the URL. The event. stopPropagation() method stops the propagation of an event from occurring in the bubbling or capturing phase.


1 Answers

This is fairly simple problem, store anywhere the last direction and coditionally execute your code:

direction = '';
window.addEventListener('wheel',  (e) => {
    if (e.deltaY < 0) {
      //scroll wheel up
      if(direction !== 'up'){
        console.log("up");
        direction = 'up';
      }
    }
    if (e.deltaY > 0) {
      //scroll wheel down
      if(direction !== 'down'){
        console.log("down");
        direction = 'down';
      }
    }
  });

Anyway, the UX context should be defined. May be that throttling or debouncing your function will give better results in some scenarios.

Throttling

Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

Debouncing

Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called.

In your case, maybe debouncing is the best option.

Temporary lock the browser scroll

$('#test').on('mousewheel DOMMouseScroll wheel', function(e) {
    e.preventDefault();
    e.stopPropagation();

    return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="test">
  <h1>1</h1>
  <h1>2</h1>
  <h1>3</h1>
  <h1>4</h1>
  <h1>5</h1>
  <h1>6</h1>
  <h1>7</h1>
  <h1>8</h1>
  <h1>9</h1>
  <h1>10</h1>
</div>
like image 72
Mosè Raguzzini Avatar answered Oct 12 '22 07:10

Mosè Raguzzini