jquery.ui.touch-punch.js 5.0 KB

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