简体   繁体   中英

setPointerCapture behaves differently in Chrome and Firefox

I have a bunch of square div inside flexboxes. When I press a mouse button inside a square, I would like the background of the target square to change. I would like to capture the mouse, so when I move the mouse outside the captured square and release the mouse button the background should change back to its original color.

This is a little difficult to describe, so here's the code. https://codepen.io/tqphan/pen/qBWaVod

window.addEventListener('mousedown', function(e) {
  e = e || window.event;
  var target = e.target || e.srcElement;
  target.classList.add("pressed")
  target.setPointerCapture(e.pointerId);
}, true);
window.addEventListener('mouseup', function(e) {
  e = e || window.event;
  var target = e.target || e.srcElement;
  target.classList.remove("pressed")
  target.releasePointerCapture(e.pointerId);
}, true);

To reproduce the problem, please follow these steps:

  1. Press the left mouse button over a square.
  2. While the left mouse button is held down, drag the mouse outside the square.
  3. Release the left mouse button.

In Firefox, it works as I expected. In Chrome, the background doesn't change back to its original color.

I tried capturing the events for window and document.

edit: It appears pointer capture and release are not executed in Chrome.

pen.js:6 Uncaught DOMException: Failed to execute 'setPointerCapture' on 'Element': No active pointer with the given id is found.

pen.js:12 Uncaught DOMException: Failed to execute 'releasePointerCapture' on 'Element': No active pointer with the given id is found.

pointerId is a property of the PointerEvent interface.

MouseEvents like mousedown doesn't inherit from PointerEvent and doesn't have a pointerId property.

What you want is to listen for pointerdown and pointerup events:

 onmousedown = e => console.log('mousedown', e.pointerId) // undefined onpointerdown = e => console.log('pointerdown', e.pointerId) // id 

That Firefox casts undefined to 0 while Chrome doesn't is an unfortunate discrepancy, but ultimately no browsers really did what you expect, since your code was broken here.

I had the same or similar problem, setPointerCapture() worked perfectly for my app on FireFox, but not on Chrome. On Chrome it seemed to do nothing, no error-messages either.

On Chrome setPointerCapture() seems to only capture "pointer events" meaning events named like 'pointermove' and 'pointerup, NOT events 'mousemove' and 'mouseup' etc. This happens on Chrome version 97.0.4692.99 (Official Build) (64-bit)

Those were the ones for which I had set event-handlers in my DOM-element. Therefore they worked fine on FireFox.

After this change it works equally well on both FireFox and Chrome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM