Skip to content

Instantly share code, notes, and snippets.

@AMHOL
Created May 22, 2013 15:37
Show Gist options
  • Save AMHOL/5628553 to your computer and use it in GitHub Desktop.
Save AMHOL/5628553 to your computer and use it in GitHub Desktop.
jQuery swipe library with support for android/iPad touch events and mouse events
(function($) {
'use strict';
// settings
$.fn.swipe = function(options) {
var args = Array.prototype.slice.call(arguments);
// bind using bind or on?
var bind = typeof $.fn.on == 'function' ? 'on' : 'bind';
var unbind = typeof $.fn.off == 'function' ? 'off' : 'unbind';
// events to bind
var events = {
start: [],
move: [],
end: []
};
var settings = $.extend({}, $.swipe.settings);
// event types to support
var supportedEventTypes = {
mouse: {
start: 'mousedown.swipe',
move: 'mousemove.swipe',
end: 'mouseup.swipe'
},
touch: {
start: 'touchstart.swipe',
move: 'touchmove.swipe',
end: 'touchend.swipe'
}
};
// configuration options
if ( !$.isPlainObject(options) && args.length ) {
options = {};
$.each(args, function(key, option) {
if ( $.isArray(option) ) {
options.excludeSupportFor = option;
} else if ( $.type(option) == 'string' ) {
if ( /^[\d+]/.test() ) {
options.registerAsSwipeAfter = option;
} else {
options.excludeSupportFor = [option];
}
} else if ( $.type(option) == 'function' ) {
options.callback = option;
}
});
}
$.extend(settings, options);
if ( $.type(settings.registerAsSwipeAfter) != 'number' ) {
settings.registerAsSwipeAfter = +settings.registerAsSwipeAfter.replace(/[^\d]/g, '');
}
if ( !$.isArray(settings.excludeSupportFor) ) {
options.excludeSupportFor = [options.excludeSupportFor];
}
if ( $.type(settings.swipeend) == 'function' && $.type(settings.callback) != 'function' ) {
settings.callback = settings.swipeend;
}
// now we can choose which events to register
// remove supported event types if in excludeSupportFor array argument
if ( $.isArray(settings.excludeSupportFor) && settings.excludeSupportFor.length ) {
$.deleteAt(supportedEventTypes, settings.excludeSupportFor);
}
// expand events to contain supported events
$.each(supportedEventTypes, function(type, supprted_events) {
$.each(supprted_events, function(key, eventType) {
events[key].push(eventType);
});
});
// the stuff that makes it swipe
var startPosition, movedToPosition;
// bind a mousedown and log co-orinates
$(this)[bind](events.start.join(' '), function(event) {
event.preventDefault();
startPosition = _normalizeEvent(event);
// bind mouse move event
$(this)[bind](events.move.join(' '), function(event) {
event.preventDefault();
movedToPosition = _normalizeEvent(event);
var eventData = _getEventData(startPosition, movedToPosition);
if ( eventData ) {
if ( Math.abs(eventData.movedBy.x) > settings.registerAsSwipeAfter || Math.abs(eventData.movedBy.y) > settings.registerAsSwipeAfter ) {
if ( $.type(settings.swipemove) == 'function' ) {
settings.swipemove.call(this, eventData);
}
$(this).trigger('swipemove', eventData);
$.swipe.isSwiping = true;
}
}
});
});
// bind mouse up event
$(this)[bind](events.end.join(' '), function() {
$(this)[unbind](events.move.join(' '));
var eventData = _getEventData(startPosition, movedToPosition);
if ( eventData ) {
if ( Math.abs(eventData.movedBy.x) > settings.registerAsSwipeAfter || Math.abs(eventData.movedBy.y) > settings.registerAsSwipeAfter ) {
$.swipe.isSwiping = false;
if ( $.type(settings.callback) == 'function' ) {
settings.callback.call(this, eventData);
}
$(this).trigger('swipeend', eventData);
}
}
startPosition = movedToPosition = null;
});
// return the event data to be passed to callback
function _getEventData(startPosition, movedToPosition) {
if ( startPosition && movedToPosition ) {
var eventData = {
movedBy: {
x: movedToPosition.x - startPosition.x,
y: movedToPosition.y - startPosition.y,
unit: 'px',
readableUnit: 'pixels'
}
};
$.extend(eventData, {
direction: {
x: eventData.movedBy.x < 0 ? 'left' : 'right',
y: eventData.movedBy.y < 0 ? 'up' : 'down'
}
});
return eventData;
}
return false;
};
// should return { x: mouseXPosition (relative to page), y: mouseYPosition (relative to page) }
function _normalizeEvent(event) {
event = _getOriginalEvent(event);
switch (event.type) {
default:
return { x: event.pageX, y: event.pageY };
break;
}
};
// get the original event with the start co-ordinates
function _getOriginalEvent(event) {
if ( event.originalEvent.touches ) {
return event.originalEvent.touches[0];
} else if ( event.originalEvent.changedTouches ) {
return event.originalEvent.changedTouches[0];
} else {
return event.originalEvent;
}
};
return this;
};
$.swipe = {
isSwiping: false,
settings: {
registerAsSwipeAfter: 10,
excludeSupportFor: [],
swipemove: null,
callback: null
}
};
// delete from array / object depending on if key is string or number
$.deleteAt = function() {
var args = Array.prototype.slice.call(arguments);
var object = args.shift();
if ( $.isArray(args[0]) ) {
args = args[0];
}
var processed = 0;
$.each(args, function(index, key) {
if ( $.type(key) == 'string' ) {
delete object[key];
} else {
if ( object.splice(key + processed, 1).length ) {
processed--;
}
}
});
return this;
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment