我正在尝试构建一个网页,用于感知用户的触摸以及画布上的拖动和对象。
所以我正在做这样的事情:
var touchStart = function(e) {
e.preventDefault();
// Do stuff
}
var touchMove = function(e) {
e.preventDefault();
console.log("Touch move");
// Move objs
}
var touchEnd = function(e) {
e.preventDefault();
console.log("Touch start!");
// clean up stuff
}
var touchCancel = function(e) {
e.preventDefault();
// Oh NO touch cancel!
console.log("Touch cancel!");
}
bindElemOrig.addEventListener('touchstart', touchStart, false);
bindElemOrig.addEventListener('touchmove', touchStart, false);
bindElemOrig.addEventListener('touchend', touchStart, false);
bindElemOrig.addEventListener('touchcancel', touchStart, false);
直到某一点它才能正常工作。
问题在于,一旦我加载太多objs,在我看来 touchmove 需要太长时间才能响应,并且 touchcancel 会被触发。问题是,只要 touchcancel 被触发,我就不会再收到 touchmove 的事件了,我再也感觉不到了。
有没有人遇到这个问题?我知道Android中你必须调用 preventDefault (touchend event in ios webkit not firing?)的错误,但在这种情况下,由于内存负担似乎无法正常工作。
谢谢!
答案 0 :(得分:3)
var touchMove = function(e) {
e.preventDefault();
setTimeout(function(){
console.log("Touch move");
// Move objs
})
}
使用setTimeout将你的逻辑包装在touchmove中可以解决这个问题
答案 1 :(得分:2)
此问题可能是由Chrome / Android中的错误(功能?)引起的。请参阅this bug report。
此测试演示了行为(JSFiddle):
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
var delay = 200;
var haltEvent = function(event) {
event.preventDefault();
event.stopPropagation();
};
var pause = function() {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + delay);
};
window.addEventListener('load', function() {
var target = document.querySelector('#target');
var status = document.querySelector('#status');
target.addEventListener('touchstart', function(event) {
haltEvent(event);
status.innerHTML = '[touchstart]';
}, true);
target.addEventListener('touchmove', function(event) {
pause();
haltEvent(event);
status.innerHTML = '[touchmove]';
}, true);
target.addEventListener('touchend', function(event) {
status.innerHTML = '[touchend]';
}, true);
target.addEventListener('touchcancel', function(event) {
status.innerHTML = '[touchcancel]';
}, true);
});
</script>
<style>
#target {
background-color: green;
height: 300px;
}
#status {
text-align: center;
}
</style>
</head>
<body>
<div id="target"></div>
<p id="status">[]</p>
</body>
</html>
我没有发现随机触发的touchcancel事件。相反,只要从touchmove事件处理程序返回约200毫秒就会触发它。
答案 2 :(得分:0)
Touchcancel专门设计用于控制触摸事件并执行常规浏览器操作,例如在非常小的触摸和移动操作后平移或缩放(近20px,具体取决于浏览器)。
您唯一的选择是:
touch-action
CSS属性as
explained here
阻止pointercancel
被解雇(推荐但需要Android 5 +)event.preventDefault()
事件处理程序中添加touchmove
,但这也会禁用任何默认操作,如滚动,平移,缩放等。你不能试图在preventDefault()
函数中取消或touchcancel
,因为它为时已晚;浏览器已停止收听touchmove
事件。这是设计,而不是错误。