Created
May 27, 2020 00:46
-
-
Save ethanny2/44d5ad69970596e96e0b48139b89154b to your computer and use it in GitHub Desktop.
Vanilla JavaScript Double tap event detection on mobile using setTimeout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Based on this http://jsfiddle.net/brettwp/J4djY/*/ | |
function detectDoubleTapClosure() { | |
let lastTap = 0; | |
let timeout; | |
return function detectDoubleTap(event) { | |
const curTime = new Date().getTime(); | |
const tapLen = curTime - lastTap; | |
if (tapLen < 500 && tapLen > 0) { | |
console.log('Double tapped!'); | |
event.preventDefault(); | |
} else { | |
timeout = setTimeout(() => { | |
clearTimeout(timeout); | |
}, 500); | |
} | |
lastTap = curTime; | |
}; | |
} | |
/* Regex test to determine if user is on mobile */ | |
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { | |
document.body.addEventListener('touchend', detectDoubleTapClosure()); | |
} |
Configuring your event listener as not passive will improve the performance of this. E.g:
document.body.addEventListener('touchend', detectDoubleTapClosure(), { passive: false });
More info here: https://dom.spec.whatwg.org/#dom-eventlisteneroptions-passive
Just putting that together with the code for easy copy. No changes.
/* Based on this http://jsfiddle.net/brettwp/J4djY/*/
function detectDoubleTapClosure() {
let lastTap = 0;
let timeout;
return function detectDoubleTap(event) {
const curTime = new Date().getTime();
const tapLen = curTime - lastTap;
if (tapLen < 500 && tapLen > 0) {
console.log('Double tapped!');
event.preventDefault();
} else {
timeout = setTimeout(() => {
clearTimeout(timeout);
}, 500);
}
lastTap = curTime;
};
}
/* Regex test to determine if user is on mobile */
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
document.body.addEventListener('touchend', detectDoubleTapClosure(), { passive: false });
}
The end of a pinch gesture will also trigger this, unless you carefully lift both fingers simultaneously.
why are you using the timeout? it doesn't do anything?
very good, I modified it a little with 3 additions:
- You can now listen for the doubletap event on any element on the page after it is initialized
- work on desktop and mobile
- customize time to detect doubletap
/* Based on ethanny2 solution: https://gist.github.com/ethanny2/44d5ad69970596e96e0b48139b89154b */
function detectDoubleTap(doubleTapMs) {
let timeout, lastTap = 0
return function detectDoubleTap(event) {
const currentTime = new Date().getTime()
const tapLength = currentTime - lastTap
if (0 < tapLength && tapLength < doubleTapMs) {
event.preventDefault()
const doubleTap = new CustomEvent("doubletap", {
bubbles: true,
detail: event
})
event.target.dispatchEvent(doubleTap)
} else {
timeout = setTimeout(() => clearTimeout(timeout), doubleTapMs)
}
lastTap = currentTime
}
}
// initialize the new event
document.addEventListener('pointerup', detectDoubleTap(500));
// put the addEventListener on some tag
document.querySelector('button').addEventListener('doubletap', (event) => {
event.target.insertAdjacentHTML("afterend", "<br>doubleTaped")
})
Working here: https://jsfiddle.net/Byte/adLxjmtw/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Smooth!