├── .gitignore ├── README.md ├── bower.json ├── package.json └── tap-listener.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | TapListener is no longer support and should be avoided. From [ftlabs/fastclick](https://github.com/ftlabs/fastclick) 4 | 5 | > As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing bugs into your application. 6 | 7 | Likewise, TapListener is no longer useful. I recommend using standard `click` event. 8 | 9 | See [Chrome dev blog - 300ms tap delay, gone away](https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away) 10 | 11 | # Tap listener 12 | 13 | _Listens to taps_ 14 | 15 | On mobile devices, the `click` event is triggered after a delay. Tap Listener listens for native touch and pointer events to trigger a callback immediately. 16 | 17 | Used in [Flickity](http://flickity.metafizzy.co). 18 | 19 | ``` js 20 | var tapper = new TapListener( element ); 21 | tapper.on( 'tap', function( event ) { 22 | console.log('tap happened'); 23 | }); 24 | ``` 25 | 26 | Use `TapListener` to extend a class. 27 | 28 | ``` js 29 | function Widget() { 30 | //... 31 | } 32 | // inherit Tap Listener 33 | Widget.prototype = new TapListener(); 34 | // or 35 | _.extend( Widget.prototype, TapListener.prototype ); 36 | 37 | var widgy = new Widget( element ); 38 | widgy.on( 'tap', function() {...}); 39 | ``` 40 | 41 | ## Install 42 | 43 | Bower: `bower install tap-listener --save` 44 | 45 | npm: `npm install tap-listener` 46 | 47 | ### RequireJS 48 | 49 | ``` js 50 | requirejs( [ 'path/to/tap-listener' ], function( TapListener ) { 51 | var tapper = new TapListener( element ); 52 | }); 53 | ``` 54 | 55 | ### Browserify 56 | 57 | ``` js 58 | var TapListener = require('tap-listener'); 59 | var tapper = new TapListener( element ); 60 | ``` 61 | 62 | ## API 63 | 64 | ``` js 65 | var tapper = new TapListener( element ) 66 | // element {Element} - binds tap events to element 67 | 68 | tapper.bindTap( element ) 69 | // element {Element} - binds tap events to element 70 | 71 | tapper.unbindTap() 72 | // unbinds tap events 73 | 74 | tapper.on( eventName, callback ) 75 | // eventName {String} - tap, pointerDown, pointerMove, pointerUp, pointerCancel 76 | // callback {Function} 77 | 78 | function callback( event, pointer ) {...} 79 | // event {Event} - the original mouseup, touchend, or pointerup event 80 | // pointer {Event} or {Touch} - event object with pageX and pageY 81 | 82 | tapper.destroy() 83 | // unbinds tap events 84 | ``` 85 | 86 | --- 87 | 88 | MIT license 89 | 90 | By [Metafizzy](http://metafizzy.co) 91 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tap-listener", 3 | "main": "tap-listener.js", 4 | "dependencies": { 5 | "unipointer": "^2.1.0" 6 | }, 7 | "authors": [ 8 | "David DeSandro" 9 | ], 10 | "description": "Listens to taps", 11 | "moduleType": [ 12 | "amd", 13 | "globals", 14 | "node" 15 | ], 16 | "keywords": [ 17 | "tap", 18 | "touch", 19 | "click", 20 | "event" 21 | ], 22 | "homepage": "https://github.com/metafizzy/tap-listener", 23 | "license": "MIT", 24 | "ignore": [ 25 | "**/.*", 26 | "node_modules", 27 | "bower_components", 28 | "test", 29 | "tests", 30 | "package.json" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tap-listener", 3 | "version": "2.0.0", 4 | "description": "Listens to taps", 5 | "main": "tap-listener.js", 6 | "dependencies": { 7 | "unipointer": "^2.1.0" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/metafizzy/tap-listener.git" 16 | }, 17 | "keywords": [ 18 | "tap", 19 | "touch", 20 | "click", 21 | "event", 22 | "browser", 23 | "DOM" 24 | ], 25 | "author": "David DeSandro", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/metafizzy/tap-listener/issues" 29 | }, 30 | "homepage": "https://github.com/metafizzy/tap-listener" 31 | } 32 | -------------------------------------------------------------------------------- /tap-listener.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Tap listener v2.0.0 3 | * listens to taps 4 | * MIT license 5 | */ 6 | 7 | /*jshint browser: true, unused: true, undef: true, strict: true */ 8 | 9 | ( function( window, factory ) { 10 | // universal module definition 11 | /*jshint strict: false*/ /*globals define, module, require */ 12 | 13 | if ( typeof define == 'function' && define.amd ) { 14 | // AMD 15 | define( [ 16 | 'unipointer/unipointer' 17 | ], function( Unipointer ) { 18 | return factory( window, Unipointer ); 19 | }); 20 | } else if ( typeof module == 'object' && module.exports ) { 21 | // CommonJS 22 | module.exports = factory( 23 | window, 24 | require('unipointer') 25 | ); 26 | } else { 27 | // browser global 28 | window.TapListener = factory( 29 | window, 30 | window.Unipointer 31 | ); 32 | } 33 | 34 | }( window, function factory( window, Unipointer ) { 35 | 36 | 'use strict'; 37 | 38 | // -------------------------- TapListener -------------------------- // 39 | 40 | function TapListener( elem ) { 41 | this.bindTap( elem ); 42 | } 43 | 44 | // inherit Unipointer & EventEmitter 45 | var proto = TapListener.prototype = Object.create( Unipointer.prototype ); 46 | 47 | /** 48 | * bind tap event to element 49 | * @param {Element} elem 50 | */ 51 | proto.bindTap = function( elem ) { 52 | if ( !elem ) { 53 | return; 54 | } 55 | this.unbindTap(); 56 | this.tapElement = elem; 57 | this._bindStartEvent( elem, true ); 58 | }; 59 | 60 | proto.unbindTap = function() { 61 | if ( !this.tapElement ) { 62 | return; 63 | } 64 | this._bindStartEvent( this.tapElement, false ); 65 | delete this.tapElement; 66 | }; 67 | 68 | /** 69 | * pointer up 70 | * @param {Event} event 71 | * @param {Event or Touch} pointer 72 | */ 73 | proto.pointerUp = function( event, pointer ) { 74 | // ignore emulated mouse up clicks 75 | if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) { 76 | return; 77 | } 78 | 79 | var pointerPoint = Unipointer.getPointerPoint( pointer ); 80 | var boundingRect = this.tapElement.getBoundingClientRect(); 81 | var scrollX = window.pageXOffset; 82 | var scrollY = window.pageYOffset; 83 | // calculate if pointer is inside tapElement 84 | var isInside = pointerPoint.x >= boundingRect.left + scrollX && 85 | pointerPoint.x <= boundingRect.right + scrollX && 86 | pointerPoint.y >= boundingRect.top + scrollY && 87 | pointerPoint.y <= boundingRect.bottom + scrollY; 88 | // trigger callback if pointer is inside element 89 | if ( isInside ) { 90 | this.emitEvent( 'tap', [ event, pointer ] ); 91 | } 92 | 93 | // set flag for emulated clicks 300ms after touchend 94 | if ( event.type != 'mouseup' ) { 95 | this.isIgnoringMouseUp = true; 96 | // reset flag after 300ms 97 | var _this = this; 98 | setTimeout( function() { 99 | delete _this.isIgnoringMouseUp; 100 | }, 400 ); 101 | } 102 | }; 103 | 104 | proto.destroy = function() { 105 | this.pointerDone(); 106 | this.unbindTap(); 107 | }; 108 | 109 | // ----- ----- // 110 | 111 | return TapListener; 112 | 113 | })); 114 | --------------------------------------------------------------------------------