Search code examples
javascriptdrag-and-droptouchlong-press

Javascript: Detecting a long press


In order to differentiate between scroll and drag&drop on touch devices I decided to consider that drag event occurred if it follows long press.

Is there a way to make code below cleaner?

const listItem = document.getElementById("listItem");
listItem.addEventListener("touchstart", onTouchstart);
listItem.addEventListener("touchmove", onTouchmove);
listItem.addEventListener("touchend", onTouchend);

const longpress = false;
const longpressStart = 0;
const longpressChecked = false;
const LONGPRESS_DURATION = 100;

function onTouchstart() {
    longpress = false;
    longpressStart = Date.now();
}

function isLongPress() {
    if (longpressChecked) {
        return longpress;
    }
    if (Date.now() - longpressStart >= LONGPRESS_DURATION) {
        longpress = true;
    }
    longpressChecked = true;
    return longpress;
}

function onTouchmove() {

    if (isLongPress()) {
        // drag and drop logic
    }
}

function onTouchend() {
    longpress = false;
    longpressStart = 0;
    longpressChecked = false;
}

Thank you for help


Solution

  • You could beautify this through using some curried arrow functions:

    const listen = (el, name) => handler => el.addEventListener(name, handler);
    
    const since = (onStart, onEnd) => {
      let last = 0;
      onStart(() => last = Date.now());
      onEnd(() => last = 0);
      return time => Date.now() - last < time;
    };
    

    So you can just do:

    const longPress = since(
       listen(listItem, "touchstart"),
       listen(listItem, "touchend")
    );
    
    listen(listItem, "touchmove")(evt => {
      if(longPress(100)) {
        //...
       }
    });