14

我正在尝试构建一个网页来感知用户的触摸并沿着画布拖动和对象。

所以我正在做这样的事情:

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);

它工作正常,直到某个时候。

问题是,一旦我加载了太多的 obj,在我看来touchmove需要很长时间才能响应,并且touchcancel会被触发。问题是一旦touchcancel被触发,我就不再收到touchmove事件,并且我再也无法感知到移动。

有人遇到过这个问题吗?我知道 Android 中的错误,您必须调用preventDefaultios webkit 中的 touchend 事件未触发?)但在这种情况下,由于内存负担,它似乎无法正常工作。

谢谢!

4

3 回答 3

3

像这样

var touchMove = function(e) {
    e.preventDefault();
    setTimeout(function(){
        console.log("Touch move");
    // Move objs

    })
}

使用 setTimeout 将你的逻辑包装在 touchmove 中可以解决这个问题

于 2014-10-14T07:41:11.240 回答
2

此问题可能是由于 Chrome/Android 中的错误(功能?)。请参阅此错误报告

此测试演示了行为(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 毫秒就会触发它。

于 2013-07-18T16:30:12.560 回答
0

Touchcancel专门设计用于控制触摸事件并在非常小的触摸和移动操作(接近 20 像素,具体取决于浏览器)后执行常规浏览器操作,例如平移或缩放。

您唯一的选择是:

  1. 切换到指针事件并使用此处解释touch-action的CSS 属性来防止触发(推荐但需要 Android 5+)pointercancel
  2. event.preventDefault()在事件处理程序中添加touchmove,但这也会禁用任何默认操作,如滚动、平移、缩放等。

您不能尝试取消或preventDefault()touchcancel函数内取消,因为为时已晚;浏览器已经停止监听touchmove事件。这是设计使然,而不是错误。

于 2017-10-06T02:58:57.443 回答