jq-mobile.js 4.9 KB

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