-1

I have the below code:

window.addEventListener('mousemove', ()=>{
   myInterval = setTimeout(mouseMove, 2000);
});

const mouseMove = () => {
    console.log('first console');
    onMouseMove = (e) => console.log("mouse location:", e.x, e.y)
}

Only at the end of the timeout I should console.log the coordinates of the mouse; however, onMouseMove is not respecting the timeout logic.

The console.log('first console') is triggered only at the end of the 2 seconds, but onMouseMove triggers with every move of the mouse.

In addition to the above, I would like to console.log only the last coordinate at the end of this 2 seconds.

I've tried changing between setInterval and setTimeout, also clearing these interval and timeout, but still didnt work as intended.

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • unclear what you think `onMouseMove = (e) => console.log("mouse location:", e.x, e.y)` is doing. You are defining a function, that is all. – epascarello Nov 09 '22 at 14:37
  • So do you want to 'throttle' the calls to every two seconds. So for a billion moves, it will only call it every 2 seconds. Do you want the position when the event was triggered or when the mouse is at when the timer runs? – epascarello Nov 09 '22 at 14:39

2 Answers2

0

The OP should use a throttle approach like the one of lodash (throttle) or underscorejs (throttle).

The advantage is to not being forced to deal with the time/out management. One just implements a simple logging function. The event handling also is done as usual with the small exception of passing a throttled version of e.g. the mouse coordinates logging as event handler.

The throttling is taken care of by a throttle method of one's choice (unless one has implemented one's own throttle functionality). Thus such a method creates a throttled version of a passed/provided function which invokes said function at most once per every milliseconds (where the latter value was passed to the method as well).

const logMouseCoords = (evt) => {
  console.log("mouse location:", evt.x, evt.y);
}
document
  .querySelector('.mousepad')
  .addEventListener('mousemove', _.throttle(logMouseCoords, 2000));
.as-console-wrapper {
  left: auto!important;
  width: 50%;
  min-height: 100%;
}
.mousepad {
  position: fixed;
  left: 0;
  top: 0;
  width: 50%;
  height: 100%;
  text-align: center;
  background-color: rgba(255, 204, 0, .3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<div class="mousepad">mousepad</div>
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
0

You want to throttle the call. There is many ways to do it, but here is a basic one where you call the function with the timeout. You set the timeout to determine if the timer is running. If it is you do not create a timeout.

const throttleMouseMove = (callback) => {
  const ms = 2000;

  let active = null;
  let x = -1;
  let y = -1;
  
  return function(evt) {
    x = evt.clientX;
    y = evt.clientY;
    if (!active) {
      active = setTimeout(() => {
        callback.apply(this, [{ x, y}] );
        active = null;
      }, ms)
    }
  }
}

const sayPosition = ({ x,y }) => {
  console.log(x,y);
}

window.addEventListener('mousemove', throttleMouseMove(sayPosition));
epascarello
  • 204,599
  • 20
  • 195
  • 236