2

I have added a wheel event-listener to an HTML element. My array has 4 variables in it. Now, my aim is that whenever the user rolls his mouse wheel/touchpad on the object where the event - listener is added, the next variable should be selected.

For example, my array is like this [apple, orange, papaya, guava]. I want to create something that will choose apple upon wheel movement, then orange upon next wheel movement, then papaya upon next wheel movement and so on.

And the same work in opposite direction (from guava to papaya to arrange for each time user rolls their mouse wheel or scrolls up the touchpad)

The issue I face are these two:

  1. the mouse wheel fires way too many times and calls the function (damnIt) too many times. Even if I write a function to iterate the array in the order I mentioned. The function being called so many times will randomize things.

  2. I am not even sure how to write a function to cause such iteration in the array. This is not my primary problem, as of now.

    var controller = document.querySelector(".main");
    var apple = document.querySelector(".box");
    var orange = document.querySelector(".box1");
    var papaya = document.querySelector(".box2");
    var guava = document.querySelector(".box3");
    var boxes = [apple,orange,papaya,guava];
    
    controller.addEventListener('wheel', damnIt);
    
    function damnIt(){
        console.log ("hey");
        //my function for array selection goes here
    }
    
Bon Leofen
  • 85
  • 2
  • 10
  • Maybe you need for debounce (like lodash debounce) function or accumulator for do action after N events. – Vladislav Sevostyanov Jul 03 '19 at 13:17
  • Thanks Vladislav. Thanks for your time on this. It was a very quick and prompt response. I will search those term and see if it fixes my problem and will update very soon on this – Bon Leofen Jul 03 '19 at 13:22
  • Maybe trouble with your mouse? Or maybe event listener added many times? Can you try to change event to 'click' and show results? – Vladislav Sevostyanov Jul 03 '19 at 13:27
  • So, if I change the event listener to click, it fires the function (damnIt) only once. I think it has got more to do with the nature of wheel listener that keeps on firing until the event has completely stopped. The issue is more with the laptops touchpad. If I use two fingers on the touchpad and swipe up for scroll gesture, The function damnIt fires too many times, flooding my console with "hey" – Bon Leofen Jul 03 '19 at 13:31
  • Maybe you should need to replace 'wheel' event to 'mousewheel' event, then add 'touchmove' event which will trigger the 'mousewheel' event. Sample: https://css-tricks.com/forums/topic/triggering-a-wheel-event-on-mobile/#post-203961 Also see: https://stackoverflow.com/questions/50688820/wheel-events-on-touch-screens – Vladislav Sevostyanov Jul 03 '19 at 13:42
  • I did not use mousewheel event as the documentations on MDN said that the event is deprecated. Thanks on letting me know about 'touchmove'. I will check that. I am starting to believe that my problem will be solved by debouncing the function which you had mentioned before and which others are also talking about. I will update on this issue soon. – Bon Leofen Jul 03 '19 at 13:46
  • This seems to work better than debounce. https://lodash.com/docs/4.17.11#throttle – Vladislav Sevostyanov Jul 03 '19 at 14:01

3 Answers3

1

For me, the 'wheel'-Event is working fine. May you have any other wheel-Listeners?

document.addEventListener('wheel', function() {
  console.log('Hi');
}.bind(this));
Sandro Schaurer
  • 416
  • 4
  • 13
  • I am sorry but it still fires the function too many times. By this time, I am not sure if I am using the correct eventlistener or not. So, my aim is that the user uses their two finger on their laptop touchpad or their mouse wheel to mimic scroll movement. But, instead of scrolling a new item is displayed on the screen. Those items are stored in array with their corresponding CSS property. I hope I was able to make my point clearer. Sorry, if I am still not clear here. – Bon Leofen Jul 03 '19 at 13:42
1

You should use throttling. There are a lot of articles on web about that. For example https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

Kostya Tresko
  • 754
  • 1
  • 5
  • 24
0

Trotting way (Call no more than once every 150 ms):

var controller = document.querySelector(".main");
var apple = document.querySelector(".box");
var orange = document.querySelector(".box1");
var papaya = document.querySelector(".box2");
var guava = document.querySelector(".box3");
var boxes = [apple,orange,papaya,guava];

controller.addEventListener('wheel', throttle(damnIt, 150));

function damnIt() {
  console.log ("hey");

    //my function for array selection goes here
}

function throttle(cb, timeout) {
  // You can rewrite this function by replacing the time limit with the
  // scroll pitch. I think that would be the best solution.
  // let delta = e.deltaY || e.detail || e.wheelDelta;
  // ... sum delta and call callback by the number of steps: accumulator/step

  let lastCall = 0;

  return function() {
    if (new Date() - lastCall > timeout) {
      lastCall = new Date();

      cb();
    }
  }
}