88 lines
2.2 KiB
JavaScript
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)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|