Skip to content

Commit

Permalink
major refactor to use simulated events. minification now done using u…
Browse files Browse the repository at this point in the history
…glify
  • Loading branch information
furf committed Nov 21, 2011
1 parent 805cfe7 commit a58ab31
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 81 deletions.
159 changes: 82 additions & 77 deletions jquery.ui.touch-punch.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

/*!
* jQuery UI Touch Punch 0.1.2
* jQuery UI Touch Punch 0.2.0
*
* Copyright 2010, Dave Furfero
* Copyright 2011, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
Expand All @@ -11,111 +10,120 @@
*/
(function ($) {

// Detect touch support
$.support.touch = typeof Touch === 'object';

// Ignore browsers without touch support
if (!$.support.touch) {
return;
}

var $doc = $(document),
mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
var mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
touchHandled;

/**
* Translate a touch event to its corresponding mouse event
* Simulate a mouse event based on a corresponding touch event
* @param {Object} event A touch event
* @param {Object} translatedType The corresponding mouse event
* @param {String} simulatedType The corresponding mouse event
*/
function translateEvent (event, translatedType) {

var touch = event.originalEvent.changedTouches[0];

return $.extend(event, {
type: 'mouse' + translatedType,
which: 1,
pageX: touch.pageX,
pageY: touch.pageY,
screenX: touch.screenX,
screenY: touch.screenY,
clientX: touch.clientX,
clientY: touch.clientY
});
function simulateMouseEvent (event, simulatedType) {

// Ignore multi-touch events
if (event.originalEvent.touches.length > 1) {
return;
}

event.preventDefault();

var touch = event.originalEvent.changedTouches[0],
simulatedEvent = document.createEvent('MouseEvents');

// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);

// Dispatch the simulated event to the target element
event.target.dispatchEvent(simulatedEvent);
}

/**
* Handle the jQuery UI widget's touchstart events
* @param {Object} event The widget element's touchstart event
*/
function _touchStart (event) {
mouseProto._touchStart = function (event) {

// Ignore the event if another widget is already being handled or if the
// gesture is multi-touch
if (touchHandled || event.originalEvent.touches.length > 1) {
// Ignore the event if another widget is already being handled
if (touchHandled) {
return;
}

// Set a flag to prevent other widgets from inheriting the touch event
// Set the flag to prevent other widgets from inheriting the touch event
touchHandled = true;

var self = this;
// Track movement to determine if interaction was a click
this._touchMoved = false;

// Trigger a pseudo-mouseover event on the target element
// @see https://github.com/hconceicao/jquery-ui-touch-punch/commit/d54be9253a432c37abcc007240145ef41aaf0b24
$(event.target).trigger(translateEvent(event, 'over'));

// Delegate the touchmove and touchend listeners to the document
$doc.bind('touchmove.' + self.widgetName, self._touchMove)
.bind('touchend.' + self.widgetName, self._touchEnd)
// By triggering mousedown on the document, we fix an error where the
// mouse widget's touchHandled never got reset because of a missing
// mousedown event on the root
// @see https://github.com/fracmak/jquery-ui-touch-punch/commit/622ef1365458c2327b1dd73ed480b26ba49e9d7d
.trigger('mousedown');

// Pass the translated touchstart event to the jQuery UI mousedown handler
self._mouseDown(translateEvent(event, 'down'));
}
// Simulate the mouseover event
simulateMouseEvent(event, 'mouseover');

// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');

// Simulate the mousedown event
simulateMouseEvent(event, 'mousedown');
};

/**
* Handle the jQuery UI widget's touchmove events
* @param {Object} event The document's touchmove event
*/
function _touchMove (event) {
mouseProto._touchMove = function (event) {

var self = this;
// Interaction was not a click
this._touchMoved = true;

// If the number of touches changes, stop tracking the original gesture
if (event.originalEvent.touches.length > 1) {
self._touchEnd(event);
} else {
// Pass the translated touchmove event to the jQuery UI mousemove
// handler
self._mouseMove(translateEvent(event, 'move'));
}
}
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
};

/**
* Handle the jQuery UI widget's touchend events
* @param {Object} event The document's touchend event
*/
function _touchEnd (event) {
mouseProto._touchEnd = function (event) {

var self = this;
// Simulate the mouseup event
simulateMouseEvent(event, 'mouseup');

// Pass the translated touchend event to the jQuery UI mouseup handler
self._mouseUp(translateEvent(event, 'up'));
// Simulate the mouseout event
simulateMouseEvent(event, 'mouseout');

// Remove listeners from document's touchmove and touchend events
$doc.unbind('touchmove.' + self.widgetName, self._touchMove)
.unbind('touchend.' + self.widgetName, self._touchEnd);
// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved) {

// Unset a flag to prevent other widgets from inheriting the touch event
touchHandled = false;
// Simulate the click event
simulateMouseEvent(event, 'click');
}

// Trigger a pseudo-mouseout event on the target element
$(event.target).trigger(translateEvent(event, 'out'));
}
// Unset the flag to allow other widgets to inherit the touch event
touchHandled = false;
};

/**
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
Expand All @@ -124,20 +132,17 @@
* original mouse event handling methods.
*/
mouseProto._mouseInit = function () {

var self = this;

// Bind the widget's touch event methods to itself to maintain scope when
// delegating its event handling to other elements
self._touchStart = $.proxy(_touchStart, self);
self._touchMove = $.proxy(_touchMove, self);
self._touchEnd = $.proxy(_touchEnd, self);

// Delegate the touchstart handler to the widget's element
self.element.bind('touchstart.' + self.widgetName, self._touchStart);
// Delegate the touch handlers to the widget's element
self.element
.bind('touchstart', $.proxy(self, '_touchStart'))
.bind('touchmove', $.proxy(self, '_touchMove'))
.bind('touchend', $.proxy(self, '_touchEnd'));

// Call the original $.ui.mouse init method
_mouseInit.call(self);
};

})(jQuery);
})(jQuery);
8 changes: 4 additions & 4 deletions jquery.ui.touch-punch.min.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* jQuery UI Touch Punch 0.1.2
/*!
* jQuery UI Touch Punch 0.2.0
*
* Copyright 2010, Dave Furfero
* Copyright 2011, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function(d){d.support.touch=typeof Touch==="object";if(!d.support.touch){return;}var b=d(document),c=d.ui.mouse.prototype,e=c._mouseInit,i;function f(k,j){var l=k.originalEvent.changedTouches[0];return d.extend(k,{type:"mouse"+j,which:1,pageX:l.pageX,pageY:l.pageY,screenX:l.screenX,screenY:l.screenY,clientX:l.clientX,clientY:l.clientY});}function a(k){if(i||k.originalEvent.touches.length>1){return;}i=true;var j=this;d(k.target).trigger(f(k,"over"));b.bind("touchmove."+j.widgetName,j._touchMove).bind("touchend."+j.widgetName,j._touchEnd).trigger("mousedown");j._mouseDown(f(k,"down"));}function g(k){var j=this;if(k.originalEvent.touches.length>1){j._touchEnd(k);}else{j._mouseMove(f(k,"move"));}}function h(k){var j=this;j._mouseUp(f(k,"up"));b.unbind("touchmove."+j.widgetName,j._touchMove).unbind("touchend."+j.widgetName,j._touchEnd);i=false;d(k.target).trigger(f(k,"out"));}c._mouseInit=function(){var j=this;j._touchStart=d.proxy(a,j);j._touchMove=d.proxy(g,j);j._touchEnd=d.proxy(h,j);j.element.bind("touchstart."+j.widgetName,j._touchStart);e.call(j);};})(jQuery);
(function(a){function e(a,b){if(a.originalEvent.touches.length>1)return;a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}a.support.touch=typeof Touch=="object";if(!a.support.touch)return;var b=a.ui.mouse.prototype,c=b._mouseInit,d;b._touchStart=function(a){if(d)return;d=!0,this._touchMoved=!1,e(a,"mouseover"),e(a,"mousemove"),e(a,"mousedown")},b._touchMove=function(a){this._touchMoved=!0,e(a,"mousemove")},b._touchEnd=function(a){e(a,"mouseup"),e(a,"mouseout"),this._touchMoved||e(a,"click"),d=!1},b._mouseInit=function(){var b=this;b.element.bind("touchstart",a.proxy(b,"_touchStart")).bind("touchmove",a.proxy(b,"_touchMove")).bind("touchend",a.proxy(b,"_touchEnd")),c.call(b)}})(jQuery);

0 comments on commit a58ab31

Please sign in to comment.