Files
2026-08-30 16:15:14 +02:00

88 lines
2.2 KiB
JavaScript

var endEvents = [
'touchend'
]
module.exports = Tap
// default tap timeout in ms
Tap.timeout = 200
function Tap(callback, options) {
options = options || {}
// if the user holds his/her finger down for more than 200ms,
// then it's not really considered a tap.
// however, you can make this configurable.
var timeout = options.timeout || Tap.timeout
// to keep track of the original listener
listener.handler = callback
return listener
// el.addEventListener('touchstart', listener)
function listener(e1) {
// tap should only happen with a single finger
if (!e1.touches || e1.touches.length > 1) return
var el = e1.target
var context = this
var args = arguments;
var timeout_id = setTimeout(cleanup, timeout)
el.addEventListener('touchmove', cleanup)
endEvents.forEach(function (event) {
el.addEventListener(event, done)
})
function done(e2) {
// since touchstart is added on the same tick
// and because of bubbling,
// it'll execute this on the same touchstart.
// this filters out the same touchstart event.
if (e1 === e2) return
cleanup()
// already handled
if (e2.defaultPrevented) return
// overwrite these functions so that they all to both start and events.
var preventDefault = e1.preventDefault
var stopPropagation = e1.stopPropagation
e1.stopPropagation = function () {
stopPropagation.call(e1)
stopPropagation.call(e2)
}
e1.preventDefault = function () {
//preventDefault.call(e1)
preventDefault.call(e2)
}
// calls the handler with the `end` event,
// but i don't think it matters.
callback.apply(context, args)
}
// cleanup end events
// to cancel the tap, just run this early
function cleanup(e2) {
// if it's the same event as the origin,
// then don't actually cleanup.
// hit issues with this - don't remember
if (e1 === e2) return
clearTimeout(timeout_id)
el.removeEventListener('touchmove', cleanup)
endEvents.forEach(function (event) {
el.removeEventListener(event, done)
})
}
}
}