/jquery.ui.ipad.js
JavaScript | 223 lines | 140 code | 46 blank | 37 comment | 17 complexity | 0ee593c4a8d09bc7115a4beb62d1b193 MD5 | raw file
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 11 12$(function() { 13 // 14 // Extend jQuery feature detection 15 // 16 $.extend($.support, { 17 touch: "ontouchend" in document 18 }); 19 20 // 21 // Hook up touch events 22 // 23 if ($.support.touch) { 24 document.addEventListener("touchstart", iPadTouchHandler, false); 25 document.addEventListener("touchmove", iPadTouchHandler, false); 26 document.addEventListener("touchend", iPadTouchHandler, false); 27 document.addEventListener("touchcancel", iPadTouchHandler, false); 28 } 29}); 30 31 32var lastTap = null; // Holds last tapped element (so we can compare for double tap) 33var tapValid = false; // Are we still in the .6 second window where a double tap can occur 34var tapTimeout = null; // The timeout reference 35 36function cancelTap() { 37 tapValid = false; 38} 39 40 41var rightClickPending = false; // Is a right click still feasible 42var rightClickEvent = null; // the original event 43var holdTimeout = null; // timeout reference 44var cancelMouseUp = false; // prevents a click from occuring as we want the context menu 45 46 47function cancelHold() { 48 if (rightClickPending) { 49 window.clearTimeout(holdTimeout); 50 rightClickPending = false; 51 rightClickEvent = null; 52 } 53} 54 55function startHold(event) { 56 if (rightClickPending) 57 return; 58 59 rightClickPending = true; // We could be performing a right click 60 rightClickEvent = (event.changedTouches)[0]; 61 holdTimeout = window.setTimeout("doRightClick();", 800); 62} 63 64 65function doRightClick() { 66 rightClickPending = false; 67 68 // 69 // We need to mouse up (as we were down) 70 // 71 var first = rightClickEvent, 72 simulatedEvent = document.createEvent("MouseEvent"); 73 simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 74 false, false, false, false, 0, null); 75 first.target.dispatchEvent(simulatedEvent); 76 77 // 78 // emulate a right click 79 // 80 simulatedEvent = document.createEvent("MouseEvent"); 81 simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 82 false, false, false, false, 2, null); 83 first.target.dispatchEvent(simulatedEvent); 84 85 // 86 // Show a context menu 87 // 88 simulatedEvent = document.createEvent("MouseEvent"); 89 simulatedEvent.initMouseEvent("contextmenu", true, true, window, 1, first.screenX + 50, first.screenY + 5, first.clientX + 50, first.clientY + 5, 90 false, false, false, false, 2, null); 91 first.target.dispatchEvent(simulatedEvent); 92 93 94 // 95 // Note:: I don't mouse up the right click here however feel free to add if required 96 // 97 98 99 cancelMouseUp = true; 100 rightClickEvent = null; // Release memory 101} 102 103 104// 105// mouse over event then mouse down 106// 107function iPadTouchStart(event) { 108 var touches = event.changedTouches, 109 first = touches[0], 110 type = "mouseover", 111 simulatedEvent = document.createEvent("MouseEvent"); 112 // 113 // Mouse over first - I have live events attached on mouse over 114 // 115 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 116 false, false, false, false, 0, null); 117 first.target.dispatchEvent(simulatedEvent); 118 119 type = "mousedown"; 120 simulatedEvent = document.createEvent("MouseEvent"); 121 122 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 123 false, false, false, false, 0, null); 124 first.target.dispatchEvent(simulatedEvent); 125 126 127 if (!tapValid) { 128 lastTap = first.target; 129 tapValid = true; 130 tapTimeout = window.setTimeout("cancelTap();", 600); 131 startHold(event); 132 } 133 else { 134 window.clearTimeout(tapTimeout); 135 136 // 137 // If a double tap is still a possibility and the elements are the same 138 // Then perform a double click 139 // 140 if (first.target == lastTap) { 141 lastTap = null; 142 tapValid = false; 143 144 type = "click"; 145 simulatedEvent = document.createEvent("MouseEvent"); 146 147 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 148 false, false, false, false, 0/*left*/, null); 149 first.target.dispatchEvent(simulatedEvent); 150 151 type = "dblclick"; 152 simulatedEvent = document.createEvent("MouseEvent"); 153 154 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 155 false, false, false, false, 0/*left*/, null); 156 first.target.dispatchEvent(simulatedEvent); 157 } 158 else { 159 lastTap = first.target; 160 tapValid = true; 161 tapTimeout = window.setTimeout("cancelTap();", 600); 162 startHold(event); 163 } 164 } 165} 166 167function iPadTouchHandler(event) { 168 var type = "", 169 button = 0; /*left*/ 170 171 if (event.touches.length > 1) 172 return; 173 174 switch (event.type) { 175 case "touchstart": 176 if ($(event.changedTouches[0].target).is("select")) { 177 return; 178 } 179 iPadTouchStart(event); /*We need to trigger two events here to support one touch drag and drop*/ 180 event.preventDefault(); 181 return false; 182 break; 183 184 case "touchmove": 185 cancelHold(); 186 type = "mousemove"; 187 event.preventDefault(); 188 break; 189 190 case "touchend": 191 if (cancelMouseUp) { 192 cancelMouseUp = false; 193 event.preventDefault(); 194 return false; 195 } 196 cancelHold(); 197 type = "mouseup"; 198 break; 199 200 default: 201 return; 202 } 203 204 var touches = event.changedTouches, 205 first = touches[0], 206 simulatedEvent = document.createEvent("MouseEvent"); 207 208 simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 209 false, false, false, false, button, null); 210 211 first.target.dispatchEvent(simulatedEvent); 212 213 if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipads default behaviour (which we prevented) 214 simulatedEvent = document.createEvent("MouseEvent"); // This check avoids click being emulated on a double tap 215 216 simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, 217 false, false, false, false, button, null); 218 219 first.target.dispatchEvent(simulatedEvent); 220 } 221} 222 223