jquery.ui.touch-punch.js 4.5 KB

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