| Current File : /home/jvzmxxx/wiki/extensions/MobileFrontend/resources/mobile.swipe/Swipe.js |
( function ( M, $ ) {
/**
* Class to assist a view in implementing swipe gestures on a specific element
*
* Use this class in a view to help it do things on swipe gestures.
*
* 1. Initialize it in the constructor `initialize` and listen to the
* 'swipe-{up|right|down|left}' events it emits (and do what you want to do)
* 2. On postRender (once we have the dom element) set it into the swipe
* object.
* 3. If you want to disable Swipe (so no events are emitted anymore), use Swipe.disable()
*
* Example:
* @example
* <code>
* var Swipe = M.require( 'mobile.swipe/Swipe' ),
* ImageOverlay = M.require( 'mobile.mediaViewer/ImageOverlay' );
* OO.mfExtend( ImageOverlayNew, ImageOverlay, {
* //...
* initialize: function ( options ) {
* var self = this;
* this.swipe = new Swipe();
* this.swipe
* .on( 'swipe-right', function () {
* self.setNewImage( $( '.slider-button.prev' ).data( 'thumbnail' ) );
* } )
* .on( 'swipe-left', function () {
* self.setNewImage( $( '.slider-button.next' ).data( 'thumbnail' ) );
* } );
* ImageOverlay.prototype.initialize.apply( this, arguments );
* },
* postRender: function () {
* if ( thumbs.length < 2 ) {
* this.$( '.prev, .next' ).remove();
* this.swipe.disable();
* } else {
* this.swipe.setElement( this.$el );
* // identify last thumbnail
* // ...
* }
* },
* } );
* </code>
*
* @class Swipe
* @extends OO.EventEmitter
*
* @constructor
*/
function Swipe() {
Swipe.super.apply( this, arguments );
this.initialize.apply( this, arguments );
}
OO.inheritClass( Swipe, OO.EventEmitter );
OO.mfExtend( Swipe, {
/**
* Constructor.
* @param {number} minDistance minimal distance in pixel between touchstart and touchend
* to be recognized as a swipe event. Default: 200
*/
initialize: function ( minDistance ) {
this.minDistance = minDistance || 200;
},
/**
* Listen to touchstart/touchend (swipe) gesture on $el
* @method
* @private
*/
_bindTouchEvents: function () {
// bind touchstart and touchend events to $el
$( this.$el )
.on( 'touchstart.mfswipe', $.proxy( this, '_onTouchStart' ) )
.on( 'touchend.mfswipe', $.proxy( this, '_onTouchEnd' ) );
},
/**
* Remove events from $el
* @method
* @private
*/
_unbindTouchEvents: function () {
$( this.$el )
.off( 'touchstart.mfswipe' )
.off( 'touchend.mfswipe' );
},
/**
* Event handler for swipe start event (touchstart)
* @param {jQuery.Event} ev
*/
_onTouchStart: function ( ev ) {
this.startTouch = ev.originalEvent.changedTouches[0];
},
/**
* Event handler for swipe finished event (touchend)
* @param {jQuery.Event} ev
*/
_onTouchEnd: function ( ev ) {
this.endTouch = ev.originalEvent.changedTouches[0];
// check if a swipe gesture is "long" enough
// horizontal swipe
if ( Math.abs( this.startTouch.pageX - this.endTouch.pageX ) > this.minDistance ) {
// recognize the swipe direction
if ( this.startTouch.pageX < this.endTouch.pageX ) {
// swiped to the right side
this.emit( 'swipe-right', ev );
} else {
// otherwise to the left side
this.emit( 'swipe-left', ev );
}
}
// vertical swipe
if ( Math.abs( this.startTouch.pageY - this.endTouch.pageY ) > this.minDistance ) {
// select the correct direction for the next image
if ( this.startTouch.pageY < this.endTouch.pageY ) {
// swiped up
this.emit( 'swipe-up', ev );
} else {
// swiped down
this.emit( 'swipe-down', ev );
}
}
},
/**
* Set the element where swipe gestures should be recognized
* @param {jQuery.Object} $el jQuery element where we want to listen for swipe
* gestures.
*/
setElement: function ( $el ) {
// unbind all events from the old element
this._unbindTouchEvents();
// set the new element
this.$el = $el;
// bind events to the new element
this._bindTouchEvents();
},
/**
* Disable swipe so that it doesn't trigger events.
* @method
*/
disable: function () {
// unbind events from the element disables swipe
this._unbindTouchEvents();
}
} );
M.define( 'mobile.swipe/Swipe', Swipe );
}( mw.mobileFrontend, jQuery ) );