Jarvis Prestidge
Jarvis Prestidge

Reputation: 326

Javascript "mousemove" event sometimes doesn't fire

I have a codepen.io example I've been working on to create a pure js collapsible side panel that is also resizable. The example works 70% of the time, but every-so-often resizing the panel will result in no "mousemove" events being emitted and the panel simply freezes (i.e. not tracking the mouse x position). I can't find the issue myself, wondering if anyone can shed some light on this one. Maybe there is a better approach to adding / removing event listeners for this kind of work that I've not thought off.

The meat of the js logic looks like the following:

const divider = document.querySelector(".divider");

const startSlide = event => {
   const viewportWidth = window.visualViewport.width;
   const width = viewportWidth - event.clientX;
   divider.style.width = `${width}px`;
};

const stopSlide = event => {
   window.removeEventListener("pointermove", startSlide, true);
   window.removeEventListener("pointerup", stopSlide, true);
};

const initSlide = event => {
   window.addEventListener("pointermove", startSlide, true);
   window.addEventListener("pointerup", stopSlide, true);
};

divider.addEventListener("pointerdown", initSlide, true);

To reproduce the issue just attempt to slide the divider panel left and right a couple of times, eventually, it will bug!

broken codepen example

Upvotes: 1

Views: 1600

Answers (2)

Jarvis Prestidge
Jarvis Prestidge

Reputation: 326

@kriddy800 put me on the right track with looking at drag events. The fix for this particular issue and many related dragging type problems is to cancel the native onDragStart event, which in turn will stop future onDrag events from firing and masking the wanted onMouseMove events.

divider.ondragstart = () => false;

A great explanation of everything drag related: https://javascript.info/mouse-drag-and-drop

Upvotes: 2

kriddy800
kriddy800

Reputation: 144

Looks like it becomes more reproducible if you quickly drag up after selecting the dividing bar. Adding a drag event listener shows that the drag on the divider is consuming the event

  divider.addEventListener("drag", function( event ) {
   console.log("DRAG");
  }, true);

You probably need to prevent the element from consuming the drag event

Upvotes: 2

Related Questions