jquery.ui.ipad.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /**
  2. * jQuery.UI.iPad plugin
  3. * Copyright (c) 2010 Stephen von Takach
  4. * licensed under MIT.
  5. * Date: 27/8/2010
  6. *
  7. * Project Home:
  8. * http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
  9. */
  10. $(function() {
  11. //
  12. // Extend jQuery feature detection
  13. //
  14. $.extend($.support, {
  15. touch: typeof Touch == "object"
  16. });
  17. //
  18. // Hook up touch events
  19. //
  20. if ($.support.touch) {
  21. document.addEventListener("touchstart", iPadTouchHandler, false);
  22. document.addEventListener("touchmove", iPadTouchHandler, false);
  23. document.addEventListener("touchend", iPadTouchHandler, false);
  24. document.addEventListener("touchcancel", iPadTouchHandler, false);
  25. }
  26. });
  27. var lastTap = null; // Holds last tapped element (so we can compare for double tap)
  28. var tapValid = false; // Are we still in the .6 second window where a double tap can occur
  29. var tapTimeout = null; // The timeout reference
  30. function cancelTap() {
  31. tapValid = false;
  32. }
  33. var rightClickPending = false; // Is a right click still feasible
  34. var rightClickEvent = null; // the original event
  35. var holdTimeout = null; // timeout reference
  36. var cancelMouseUp = false; // prevents a click from occuring as we want the context menu
  37. function cancelHold() {
  38. if (rightClickPending) {
  39. window.clearTimeout(holdTimeout);
  40. rightClickPending = false;
  41. rightClickEvent = null;
  42. }
  43. }
  44. function startHold(event) {
  45. if (rightClickPending)
  46. return;
  47. rightClickPending = true; // We could be performing a right click
  48. rightClickEvent = (event.changedTouches)[0];
  49. holdTimeout = window.setTimeout("doRightClick();", 800);
  50. }
  51. function doRightClick() {
  52. rightClickPending = false;
  53. //
  54. // We need to mouse up (as we were down)
  55. //
  56. var first = rightClickEvent,
  57. simulatedEvent = document.createEvent("MouseEvent");
  58. simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  59. false, false, false, false, 0, null);
  60. first.target.dispatchEvent(simulatedEvent);
  61. //
  62. // emulate a right click
  63. //
  64. simulatedEvent = document.createEvent("MouseEvent");
  65. simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  66. false, false, false, false, 2, null);
  67. first.target.dispatchEvent(simulatedEvent);
  68. //
  69. // Show a context menu
  70. //
  71. simulatedEvent = document.createEvent("MouseEvent");
  72. simulatedEvent.initMouseEvent("contextmenu", true, true, window, 1, first.screenX + 50, first.screenY + 5, first.clientX + 50, first.clientY + 5,
  73. false, false, false, false, 2, null);
  74. first.target.dispatchEvent(simulatedEvent);
  75. //
  76. // Note:: I don't mouse up the right click here however feel free to add if required
  77. //
  78. cancelMouseUp = true;
  79. rightClickEvent = null; // Release memory
  80. }
  81. //
  82. // mouse over event then mouse down
  83. //
  84. function iPadTouchStart(event) {
  85. var touches = event.changedTouches,
  86. first = touches[0],
  87. type = "mouseover",
  88. simulatedEvent = document.createEvent("MouseEvent");
  89. //
  90. // Mouse over first - I have live events attached on mouse over
  91. //
  92. simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  93. false, false, false, false, 0, null);
  94. first.target.dispatchEvent(simulatedEvent);
  95. type = "mousedown";
  96. simulatedEvent = document.createEvent("MouseEvent");
  97. simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  98. false, false, false, false, 0, null);
  99. first.target.dispatchEvent(simulatedEvent);
  100. if (!tapValid) {
  101. lastTap = first.target;
  102. tapValid = true;
  103. tapTimeout = window.setTimeout("cancelTap();", 600);
  104. startHold(event);
  105. }
  106. else {
  107. window.clearTimeout(tapTimeout);
  108. //
  109. // If a double tap is still a possibility and the elements are the same
  110. // Then perform a double click
  111. //
  112. if (first.target == lastTap) {
  113. lastTap = null;
  114. tapValid = false;
  115. type = "click";
  116. simulatedEvent = document.createEvent("MouseEvent");
  117. simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  118. false, false, false, false, 0/*left*/, null);
  119. first.target.dispatchEvent(simulatedEvent);
  120. type = "dblclick";
  121. simulatedEvent = document.createEvent("MouseEvent");
  122. simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  123. false, false, false, false, 0/*left*/, null);
  124. first.target.dispatchEvent(simulatedEvent);
  125. }
  126. else {
  127. lastTap = first.target;
  128. tapValid = true;
  129. tapTimeout = window.setTimeout("cancelTap();", 600);
  130. startHold(event);
  131. }
  132. }
  133. }
  134. function iPadTouchHandler(event) {
  135. var type = "",
  136. button = 0; /*left*/
  137. if (event.touches.length > 1)
  138. return;
  139. switch (event.type) {
  140. case "touchstart":
  141. if ($(event.changedTouches[0].target).is("select")) {
  142. return;
  143. }
  144. iPadTouchStart(event); /*We need to trigger two events here to support one touch drag and drop*/
  145. event.preventDefault();
  146. return false;
  147. break;
  148. case "touchmove":
  149. cancelHold();
  150. type = "mousemove";
  151. event.preventDefault();
  152. break;
  153. case "touchend":
  154. if (cancelMouseUp) {
  155. cancelMouseUp = false;
  156. event.preventDefault();
  157. return false;
  158. }
  159. cancelHold();
  160. type = "mouseup";
  161. break;
  162. default:
  163. return;
  164. }
  165. var touches = event.changedTouches,
  166. first = touches[0],
  167. simulatedEvent = document.createEvent("MouseEvent");
  168. simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  169. false, false, false, false, button, null);
  170. first.target.dispatchEvent(simulatedEvent);
  171. if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipads default behaviour (which we prevented)
  172. simulatedEvent = document.createEvent("MouseEvent"); // This check avoids click being emulated on a double tap
  173. simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,
  174. false, false, false, false, button, null);
  175. first.target.dispatchEvent(simulatedEvent);
  176. }
  177. }