0

Suppose I want to use both touch, and mouse (mouse, and touch screen might be available).

There is at least one way to deal.

When the touch fires use preventDefault (first way):

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

What if instead we do this (second way):

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

Is the second way viable for handling both touch, and mouse? The first way is recommended, but I'm interested in the possibility of using either way as long as there isn't unforeseen problems.

Quentin Engles
  • 2,744
  • 1
  • 20
  • 33

2 Answers2

1

In my opinion, the second approach is not a good solution because:

  1. Performance: You are handling 2 events (touch and mouse). The first solution prevents mouse event from firing, so your application is doing less event handling.

  2. Complexity: didTouch is adding unnecessary complexity to your code... as a general rule of thumb, if you can achieve the same result by writing less code, the the shorter solution is preferred, unless there is a valid benefit in using the longer solution.

Another potential problem to keep in mind is Mutual Exclusion. JavaScript is Thread Safe and you don't really need to worry about a second event firing and changing your didTouch flag, while you are still processing the first event. But keep in mind that it is not impossible to run into mutex problems with async methods.

Hooman Bahreini
  • 14,480
  • 11
  • 70
  • 137
  • I think this mostly answers my question. Will it be mostly safe? If I keep good limited scope for any didTouch variable do you think mutex problems can be avoided well? – Quentin Engles Jan 18 '19 at 23:31
  • My suggestion was not to use the second method.. because of performance, complexity and potential mutex problem... I am no expert on this, but all the documentation that I have seen on this problem, use your first method... not sure, why would you like to use this second method? what is the benefit? – Hooman Bahreini Jan 19 '19 at 00:04
  • I have an interesting in combing pointing events with causing automatic scroll. Like a drag used in a scrolling box where it's uncomfortable to use the left mouse button with the scroll wheel or the behavior is just expected but not available for touch. It's a very special problem to say the least. To do it properly the position of the pointing device needs to be recorded for every pixel movement. The main reason to do touch and mouse is for compatibility with other libraries that chose to preventDefault that will stop mouse any way and there's other issues like diameter precision. – Quentin Engles Jan 19 '19 at 01:17
0

I had this problem one time, but with other events, check my solution:

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);
}
Walker Leite
  • 223
  • 1
  • 7
  • This works for one or the other but not when both are available. For instance when mouse and touch monitor are being used alternately. – Quentin Engles Jan 18 '19 at 23:33