jquery.ui.touch-punch.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*!
  2. *
  3. * This library has been modified! This function has been changed: mouseProto._mouseInit
  4. *
  5. * Original Version:
  6. *
  7. * mouseProto._mouseInit = function () {
  8. *
  9. * var self = this;
  10. *
  11. * // Delegate the touch handlers to the widget's element
  12. * self.element.bind({
  13. * touchstart: $.proxy(self, '_touchStart'),
  14. * touchmove: $.proxy(self, '_touchMove'),
  15. * touchend: $.proxy(self, '_touchEnd')
  16. * });
  17. *
  18. * // Call the original $.ui.mouse init method
  19. * _mouseInit.call(self);
  20. * };
  21. *
  22. *
  23. * New Version:
  24. *
  25. * mouseProto._mouseInit = function () {
  26. *
  27. * var self = this;
  28. *
  29. * // Delegate the touch handlers to the widget's element
  30. * self.element
  31. * .bind('taphold', $.proxy(self, '_touchStart')) // IMPORTANT!MOD FOR TAPHOLD TO START SORTABLE
  32. * .bind('touchmove', $.proxy(self, '_touchMove'))
  33. * .bind('touchend', $.proxy(self, '_touchEnd'));
  34. *
  35. * // Call the original $.ui.mouse init method
  36. * _mouseInit.call(self);
  37. * };
  38. *
  39. * Why?
  40. *
  41. * The original version mapped any tap start to a click. This means that you weren't able to scroll through
  42. * the sortable on a mobile device, as every attempt to scroll was intercepted as a click.
  43. *
  44. * jQuery UI Touch Punch 0.2.3
  45. *
  46. * Copyright 2011–2014, Dave Furfero
  47. * Dual licensed under the MIT or GPL Version 2 licenses.
  48. *
  49. * Depends:
  50. * jquery.ui.widget.js
  51. * jquery.ui.mouse.js
  52. */
  53. (function ($) {
  54. // Detect touch support
  55. $.support.touch = 'ontouchend' in document;
  56. // Ignore browsers without touch support
  57. if (!$.support.touch) {
  58. return;
  59. }
  60. var mouseProto = $.ui.mouse.prototype,
  61. _mouseInit = mouseProto._mouseInit,
  62. _mouseDestroy = mouseProto._mouseDestroy,
  63. touchHandled;
  64. /**
  65. * Simulate a mouse event based on a corresponding touch event
  66. * @param {Object} event A touch event
  67. * @param {String} simulatedType The corresponding mouse event
  68. */
  69. function simulateMouseEvent (event, simulatedType) {
  70. // Ignore multi-touch events
  71. if (event.originalEvent.touches.length > 1) {
  72. return;
  73. }
  74. event.preventDefault();
  75. var touch = event.originalEvent.changedTouches[0],
  76. simulatedEvent = document.createEvent('MouseEvents');
  77. // Initialize the simulated mouse event using the touch event's coordinates
  78. simulatedEvent.initMouseEvent(
  79. simulatedType, // type
  80. true, // bubbles
  81. true, // cancelable
  82. window, // view
  83. 1, // detail
  84. touch.screenX, // screenX
  85. touch.screenY, // screenY
  86. touch.clientX, // clientX
  87. touch.clientY, // clientY
  88. false, // ctrlKey
  89. false, // altKey
  90. false, // shiftKey
  91. false, // metaKey
  92. 0, // button
  93. null // relatedTarget
  94. );
  95. // Dispatch the simulated event to the target element
  96. event.target.dispatchEvent(simulatedEvent);
  97. }
  98. /**
  99. * Handle the jQuery UI widget's touchstart events
  100. * @param {Object} event The widget element's touchstart event
  101. */
  102. mouseProto._touchStart = function (event) {
  103. var self = this;
  104. // Ignore the event if another widget is already being handled
  105. if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
  106. return;
  107. }
  108. // Set the flag to prevent other widgets from inheriting the touch event
  109. touchHandled = true;
  110. // Track movement to determine if interaction was a click
  111. self._touchMoved = false;
  112. // Simulate the mouseover event
  113. simulateMouseEvent(event, 'mouseover');
  114. // Simulate the mousemove event
  115. simulateMouseEvent(event, 'mousemove');
  116. // Simulate the mousedown event
  117. simulateMouseEvent(event, 'mousedown');
  118. };
  119. /**
  120. * Handle the jQuery UI widget's touchmove events
  121. * @param {Object} event The document's touchmove event
  122. */
  123. mouseProto._touchMove = function (event) {
  124. // Ignore event if not handled
  125. if (!touchHandled) {
  126. return;
  127. }
  128. // Interaction was not a click
  129. this._touchMoved = true;
  130. // Simulate the mousemove event
  131. simulateMouseEvent(event, 'mousemove');
  132. };
  133. /**
  134. * Handle the jQuery UI widget's touchend events
  135. * @param {Object} event The document's touchend event
  136. */
  137. mouseProto._touchEnd = function (event) {
  138. // Ignore event if not handled
  139. if (!touchHandled) {
  140. return;
  141. }
  142. // Simulate the mouseup event
  143. simulateMouseEvent(event, 'mouseup');
  144. // Simulate the mouseout event
  145. simulateMouseEvent(event, 'mouseout');
  146. // If the touch interaction did not move, it should trigger a click
  147. if (!this._touchMoved) {
  148. // Simulate the click event
  149. simulateMouseEvent(event, 'click');
  150. }
  151. // Unset the flag to allow other widgets to inherit the touch event
  152. touchHandled = false;
  153. };
  154. /**
  155. * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
  156. * This method extends the widget with bound touch event handlers that
  157. * translate touch events to mouse events and pass them to the widget's
  158. * original mouse event handling methods.
  159. */
  160. mouseProto._mouseInit = function () {
  161. var self = this;
  162. // Delegate the touch handlers to the widget's element
  163. self.element
  164. .bind('taphold', $.proxy(self, '_touchStart')) // IMPORTANT!MOD FOR TAPHOLD TO START SORTABLE
  165. .bind('touchmove', $.proxy(self, '_touchMove'))
  166. .bind('touchend', $.proxy(self, '_touchEnd'));
  167. // Call the original $.ui.mouse init method
  168. _mouseInit.call(self);
  169. };
  170. /**
  171. * Remove the touch event handlers
  172. */
  173. mouseProto._mouseDestroy = function () {
  174. var self = this;
  175. // Delegate the touch handlers to the widget's element
  176. self.element.unbind({
  177. touchstart: $.proxy(self, '_touchStart'),
  178. touchmove: $.proxy(self, '_touchMove'),
  179. touchend: $.proxy(self, '_touchEnd')
  180. });
  181. // Call the original $.ui.mouse destroy method
  182. _mouseDestroy.call(self);
  183. };
  184. })(jQuery);