use*_*947 11 javascript android google-chrome pointer-events
我在可滚动区域中有一堆子 div,如下所示:
<div style='overflow: scroll;'>
<div id='a' />
<div id='b' />
<div id='c' />
...
</div>
Run Code Online (Sandbox Code Playgroud)
我监听每个子项上的pointerdown 事件,当事件触发时,我在文档上设置pointermove 处理程序。例如:
const pointerdownHandle = e => {
e.target.releasePointerCapture(e.pointerId)
document.addEventListener('pointermove', pointermoveHandle)
document.addEventListener('pointerup', pointerupHandle)
}
const pointermoveHandle = e => { ... }
const pointerupHandle = {
document.removeEventListener('pointermove', pointermoveHandle)
document.removeEventListener('pointerup', pointerupHandle)
}
document.getElementById('a').addEventListener('pointerdown', pointerdownHandle)
Run Code Online (Sandbox Code Playgroud)
这在桌面和 iOS Safari 上都非常有效。然而在 Android Chrome 上,pointercancel 事件几乎立即触发,从而破坏了一切。
这似乎是预期的行为: “当浏览器确定不可能再有任何指针事件时,将触发pointercancel事件,或者如果在触发pointerdown事件后,然后使用指针通过平移来操作视口,缩放或滚动。”
推荐的解决方案是将 css 属性“touch-action: none”应用于父元素。这有效。但不幸的是,这也会中断滚动,因为现在触摸操作被忽略。
我尝试在pointerdown事件触发后以编程方式应用css属性,但这不起作用。将 PreventDefault / stopPropagation 添加到pointermoveHandle 也不会。
有人能解决这个问题吗?如何在不禁用父元素滚动的情况下阻止 pointcancel 事件触发?
(我意识到我可以依靠触摸事件,但是支持pointerenter和pointerleave的指针事件使用起来更加简单和干净......)
您正在使用releasePointerCapture,但我认为您可能想做完全相反的事情。指针捕获将移动事件定向到您的元素,这样您就不必在 上放置事件处理程序document。
即使我在其他地方使用指针事件,我也必须使用一次触摸事件来取消滚动。我无法弄清楚如何使用指针事件来取消滚动。
function makeDraggable(element) {
let pos = {x: 0, y: 0}
let dragging = false
const stopScrollEvents = (event) => {
event.preventDefault()
}
const pointerdownHandle = (event) => {
dragging = {dx: pos.x - event.clientX, dy: pos.y - event.clientY}
element.classList.add('dragging')
element.setPointerCapture(event.pointerId)
}
const pointerupHandle = (event ) => {
dragging = null
element.classList.remove('dragging')
}
const pointermoveHandle = (event) => {
if (!dragging) return
pos.x = event.clientX + dragging.dx
pos.y = event.clientY + dragging.dy
element.style.transform = `translate(${pos.x}px, ${pos.y}px)`
}
element.addEventListener('pointerdown', pointerdownHandle)
element.addEventListener('pointerup', pointerupHandle)
element.addEventListener('pointercancel', pointerupHandle)
element.addEventListener('pointermove', pointermoveHandle)
element.addEventListener('touchstart', stopScrollEvents)
}
for (let element of document.querySelectorAll("#draggable-children > div")) {
makeDraggable(element)
}Run Code Online (Sandbox Code Playgroud)
#draggable-children {
width: 100%;
height: 100%;
min-height: 5em;
background: #eee;
border: 1px solid black;
}
#draggable-children > div {
width: 5em;
height: 1.5em;
background: #88a;
border: 1px solid black;
cursor: grab;
}
#draggable-children > div.dragging {
width: 5em;
height: 1.5em;
background: #aa8;
border: 1px solid black;
cursor: grabbing;
}Run Code Online (Sandbox Code Playgroud)
<div id="draggable-children">
<div></div>
<div></div>
<div></div>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2176 次 |
| 最近记录: |