Xander
Xander

Reputation: 397

Javascript - Do something during long touch, stop on touch end (Android)

What I'm trying to accomplish is an input number field that increases as long as a button is held on a touch screen, and stop incrementing whenever the button is released.

HTML

<button id="inc-val">+</button>
<input id="qty-bottom" value="1">

Javascript

var node = document.getElementById('inc-val');
var longpress = false;
var timer = null;
var longtarget = null;

var cancel = function (e) {

clearTimeout(timer);
clearInterval(increm);


};

var click = function (e) {
if (timer !== null) {
    clearTimeout(timer);
    clearInterval(increm);
}

if (longpress) {
    return false;
}

document.getElementById('qty-bottom').value++;

};

var start = function (e) {
console.log(e);

if (e.type === "click" && e.button !== 0) {
    return;
}

longpress = false;

timer = setTimeout(function () {
    increm = setInterval(function () {
        document.getElementById('qty-bottom').value++;
    }, 300);
}, 10);

return false;
};

node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseup", cancel);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);

Works perfectly so far on a desktop, and on an iPhone in Safari. The issue I'm having is trying to get it to work on Android. On an Android device (in Chrome), whenever I let go of the + sign or drag my finger out of the button, it keeps incrementing endlessly.

Here is a fiddle:

https://jsfiddle.net/s77vsLxp/

(Result page easier to use on an Android) https://jsfiddle.net/s77vsLxp/embedded/result/

My end goal is to get it so a single short press raises the value by 1, while holding raises the value by 1 every 300ms. Stumped on why this works on anything but Android.

Upvotes: 1

Views: 1530

Answers (1)

Chris
Chris

Reputation: 26

It looks like long-pressing in Chrome for Android causes both mousedown and touchstart to fire, which is causing setInterval to be called twice. One fix would be to put a guard around where you are calling setTimeout/setInterval, then set timer to null on cancel.

See https://jsfiddle.net/4je2n3e8/

Upvotes: 1

Related Questions