Tha*_*Guy 5 javascript safari ios
尝试在触摸和手写笔输入上使用指针捕获时,iOS 13/14 似乎存在错误。问题在于,setPointerCapture当在不是事件原始目标的元素上调用时,调用实际上并没有重定向未来的事件。但是,调用hasPointerCapture仍然有效并按true预期返回。有什么办法可以对这个问题进行功能测试,以便为它实现一个polyfill?
如果有帮助,我在 GitHub 上为这个问题创建了一个演示。如果指针在相应的元素上开始,绿色和黄色 div 将正确跟踪指针移动,但橙色 div 的行为应相同,红色 div 不应移动。只要指针停留在 div 上,后者仍然会跟踪指针。
我目前用于填充错误的代码如下。它可以工作,但它的检测过程是一个 UA 字符串测试,因此即使它们共享相同的 JavaScript 引擎,它也不会在其他 iOS 浏览器中工作。
// Need to figure out some way to test if this is needed.
if (navigator.userAgent.match(/Version\/1[34]\.\d+(?:\.\d+)? Safari/)) {
const {
setPointerCapture: set,
hasPointerCapture: has,
releasePointerCapture: release
} = Element.prototype
let targets = {},
captures = {}
Element.prototype.setPointerCapture = function setPointerCapture(pointerId) {
if (pointerId in captures) {
if (document.contains(this)) {
captures[pointerId] = this
return set.call(targets[pointerId], pointerId)
} else {
throw new TypeError("Element not in valid location")
}
} else {
return set.call(this, pointerId)
}
}
Element.prototype.hasPointerCapture = function hasPointerCapture(pointerId) {
if (pointerId in captures) {
return captures[pointerId] == this
} else {
return has.call(this, pointerId)
}
}
Element.prototype.releasePointerCapture = function releasePointerCapture(pointerId) {
if (pointerId in captures) {
if (this.hasPointerCapture(pointerId)) {
captures[pointerId] = null
return release.call(targets[pointerId], pointerId)
}
} else {
return release.call(this, pointerId)
}
}
let registerPointer = function registerPointer(event) {
if (event.pointerType == "touch" || event.pointerType == "pen") {
targets[event.pointerId] = event.target
captures[event.pointerId] = null
}
},
redirectPointer = function redirectPointer(event) {
if (captures[event.pointerId] != null && captures[event.pointerId] != event.target) {
// Stop the original event
event.preventDefault()
event.stopPropagation()
// Redispatch a new, cloned event
captures[event.pointerId].dispatchEvent(new PointerEvent(event.type, event))
}
},
redirectAndUnregisterPointer = function redirectAndUnregisterPointer(event) {
redirectPointer(event)
delete targets[event.pointerId]
delete captures[event.pointerId]
}
addEventListener("pointerdown", registerPointer, {capture: true, passive: true})
addEventListener("pointermove", redirectPointer, {capture: true, passive: false})
addEventListener("pointerup", redirectAndUnregisterPointer, {capture: true, passive: false})
addEventListener("pointercancel", redirectAndUnregisterPointer, {capture: true, passive: false})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
155 次 |
| 最近记录: |