为什么在 DOM 更改后未触发 touchmove 事件?

Why touchmove event is not fired after DOM changes?

将我的应用程序从鼠标事件移至触摸事件时,我注意到一些奇怪的行为。基本上,touchmove 在 DOM 更改后停止工作。鼠标事件在相同情况下工作正常。我使用 chrome 开发人员工具以及 firefox 对其进行了测试。他们似乎同意结果。是错误还是我遗漏了什么?

我创建了非常简单的代码示例来证明问题与我使用的任何框架或库无关。我还发现 seemingly related question 不幸的是没有解决方案。

触摸演示:

window.addEventListener("touchmove", onTouchMove, {passive: false})

document.addEventListener('DOMContentLoaded', function(){ 
  var elem = document.getElementById("nice");
  console.log(elem)
  elem.addEventListener("touchstart", onTouchStart)
})

function onTouchMove(event) {
  console.log("touch move")
}

function onTouchStart(event) {
  console.log("touch start")
  var elem = document.getElementById("nice")
  elem.remove()
}
<!DOCTYPE html>
<html>
<body style="width: 100%; height: 100%; background-color: yellow">
  <div style="position: absolute; width: 100px; height: 100px; background-color: red; left: 100px; top: 100px" id="nice"></div>
</body>
</html>

鼠标演示:

window.addEventListener("mousemove", onMouseMove, {passive: false})

document.addEventListener('DOMContentLoaded', function(){ 
  var elem = document.getElementById("nice");
  console.log(elem)
  elem.addEventListener("mousedown", onMouseDown)
})

function onMouseMove(event) {
  console.log("mouse move")
}

function onMouseDown(event) {
  console.log("mouse start")
  var elem = document.getElementById("nice")
  elem.remove()
}
<!DOCTYPE html>
<html>
<body style="width: 100%; height: 100%; background-color: yellow">
  <div style="position: absolute; width: 100px; height: 100px; background-color: red; left: 100px; top: 100px" id="nice"></div>
</body>
</html>

一个从红色方块开始的连续拖动手势应该导致 1) 'start' 日志中的消息,2) 该方块消失,在这种情况下是 DOM 变化 3) 顺序'move' 日志中的消息。在mouse demo中是这样,但是在touch demo中方块消失后没有'move'事件。

如果您的元素被删除,这是预期的行为。

根据 docs,如果您删除一个元素,事件仍将针对它,因此不一定会再冒泡到 window 或文档。

所以如果要删除元素,有两种解决方法。您可以修改 "remove" 方法,使其仅在触摸过程结束之前隐藏元素,或者您可以将事件附加到目标本身。

这里有一个例子,你可以看到window touchmove 事件没有出现,而元素的touchmove 事件即使在元素被删除后也会出现。

window.addEventListener("touchmove", onTouchMoveWindow, {passive: false})

document.addEventListener('DOMContentLoaded', function(){ 
  var elem = document.getElementById("nice");
  console.log(elem)
  elem.addEventListener("touchstart", onTouchStart)
  elem.addEventListener("touchmove", onTouchMoveElement)
})

function onTouchMoveWindow(event) {
  console.log("touch move window")
}

function onTouchMoveElement(event) {
  console.log("touch move element")
}

function onTouchStart(event) {
  console.log("touch start")
  var elem = document.getElementById("nice")
  elem.remove()
}
<!DOCTYPE html>
<html>
<body style="width: 100%; height: 100%; background-color: yellow">
  <div style="position: absolute; width: 100px; height: 100px; background-color: red; left: 100px; top: 100px" id="nice"></div>
</body>
</html>

相关问题: