当检测到 pointermove 时,鼠标在 link 上的操作不会触发 pointerup 事件

pointerup event does not fire for mouse actions on a link when pointermove has been detected

我无法让 pointerup 事件在 link(具有 href 属性集的 A 标签)上触发 event.pointerType == 'mouse'如果鼠标在 pointerdownpointerup 之间移动。

我有以下场景:

var lastEvent = false;
var handler = function (e) {
  if (lastEvent != e.type) {
    e.target.innerHTML += e.type + ' with ' + e.pointerType + '<br/>';
    e.target.scrollTo(0, e.target.scrollHeight);
  }
  lastEvent = e.type;
}
document.querySelector('a').addEventListener('pointerdown', handler);
document.querySelector('a').addEventListener('pointermove', handler);
document.querySelector('a').addEventListener('pointerup', handler);
div {
  height: 100vh;
  display: flex;
}
a {
  height: 60vh;
  width: 75vw;
  margin: auto;
  background-color: red;
  display: inline-block;
  user-select: none;
  touch-action: none;
  overflow-y: scroll;
}
<div>
    <a href="#"></a>
</div>

如果我按下鼠标按钮,按住一段时间然后松开,我得到这个序列:

  1. 用鼠标按下指针
  2. 用鼠标向上移动指针

但是,如果我按下鼠标按钮,按住它并四处移动鼠标指针,然后松开它,我得到这个序列:

  1. 用鼠标按下指针
  2. 鼠标指针移动

问题:pointerup 永远不会触发。

我猜是浏览器内置的点击或拖动功能(我在 Chrome 中测试过)阻止了 pointerup 事件的触发,因为如果在a span 或从锚 link 中删除 href 它适用于以下序列:

  1. 用鼠标按下指针
  2. 鼠标指针移动
  3. 用鼠标向上移动指针

此外,它在触摸驱动下完美运行PointerEvents:

  1. 带触摸的指针向下
  2. 指针随触摸移动
  3. 带触摸的指针向上

我想可以在元素上设置一个聪明的 css 属性 来禁用此 pointerup 预防措施。类似于 a { pointer-actions: click; },但我没能找到什么。

哦!我基本上在问题中陈述了答案。 拖动操作 阻止了 pointerup 事件的触发。只需在 link 元素上添加 draggable="false" 属性即可解决此问题。

<a href="#" draggable="false"></a>

概念验证:

var lastEvent = false;
var handler = function (e) {
  if (lastEvent != e.type) {
    e.target.innerHTML += e.type + ' with ' + e.pointerType + '<br/>';
    e.target.scrollTo(0, e.target.scrollHeight);
  }
  lastEvent = e.type;
}
document.querySelector('a').addEventListener('pointerdown', handler);
document.querySelector('a').addEventListener('pointermove', handler);
document.querySelector('a').addEventListener('pointerup', handler);
div {
  height: 100vh;
  display: flex;
}
a {
  height: 60vh;
  width: 75vw;
  margin: auto;
  background-color: red;
  display: inline-block;
  user-select: none;
  touch-action: none;
  overflow-y: scroll;
}
<div>
    <a href="#" draggable="false"></a>
</div>

唯一的缺点是 draggable 设置为 false,所有 mousedown-mousemove-mouseup 都会触发 click事件。但这可以通过检查 pointerdownpointerup 事件之间 clientX/clientY 的差异是否大于一定数量的像素来防止,将其存储在变量中,然后在这种情况下添加一个运行 e.preventDefault(); e.stopPropagation();click 事件处理程序。