preventDefault 与 if 检查是否跳过处理鼠标和触摸?

preventDefault versus if check skip handling mouse and touch?

假设我想同时使用触摸和鼠标(鼠标和触摸屏可能可用)。

至少有一种交易方式。

当触摸触发时使用 preventDefault(第一种方式):

let onMove = event => {
    //either touch, or mouse
};

document.body.addEventListener('touchmove', event=>{
    //prevent mouse if this event fires
    event.preventDefault();
    onMove(event);
}, false);

document.body.addEventListener('mousemove', event=>{
    onMove(event);
}, false);

如果我们这样做会怎么样(第二种方式):

let didTouch = false;

let onMove = event => {
    //either touch, or mouse
};

document.body.addEventListener('touchmove', event=>{
    didTouch = true;
    onMove(event);
}, false);

document.body.addEventListener('mousemove', event=>{
    if(didTouch){
        didTouch = false;
    }else{
        onMove(event);
    }
}, false);

第二种方式是否可以同时处理触摸和鼠标?推荐第一种方式,但我对使用任何一种方式的可能性感兴趣,只要没有不可预见的问题。

在我看来,第二种方法不是一个好的解决方案,因为:

  1. 性能:您正在处理 2 个事件(触摸和鼠标)。第一个解决方案阻止鼠标事件触发,因此您的应用程序处理的事件较少。

  2. 复杂性:didTouch 为您的代码增加了不必要的复杂性...作为一般经验法则,如果您可以通过编写更少的代码来实现相同的结果,则解决方案越短是首选,除非使用更长的解决方案有实际好处。

另一个需要牢记的潜在问题是互斥。 JavaScript is Thread Safe 并且你真的不需要担心第二个事件触发和改变你的 didTouch 标志,而你仍在处理第一个事件。但请记住,使用异步方法 运行 解决互斥锁问题并非不可能。

我遇到过一次这个问题,但对于其他事件,请查看我的解决方案:

let handler = function (e) {
  // do stuff
};

if (isTouchDevice()) {
  key.addEventListener('touchstart', handler);
} else {
  key.addEventListener('mousedown', handler);
}

function isTouchDevice() {
  var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
  var mq = function (query) {
    return window.matchMedia(query).matches;
  };
  if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
    return true;
  }

  // include the 'heartz' as a way to have a non matching MQ to help terminate the join
  // https://git.io/vznFH
  var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
  return mq(query);
}