Created
September 30, 2011 13:46
-
-
Save holywarez/1253775 to your computer and use it in GitHub Desktop.
jQuery UI support on iOS where need it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* jQuery.UI.iPad plugin | |
* Copyright (c) 2010 Stephen von Takach | |
* licensed under MIT. | |
* Date: 27/8/2010 | |
* | |
* Project Home: | |
* http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ | |
*/ | |
(function ($) { | |
$(function() { | |
// | |
// Extend jQuery feature detection | |
// | |
$.extend($.support, { | |
touch: "ontouchend" in document | |
}); | |
// | |
// Hook up touch events | |
// | |
// if ($.support.touch) { | |
// document.addEventListener("touchstart", iPadTouchHandler, false); | |
// document.addEventListener("touchmove", iPadTouchHandler, false); | |
// document.addEventListener("touchend", iPadTouchHandler, false); | |
// document.addEventListener("touchcancel", iPadTouchHandler, false); | |
// } | |
// | |
// Hook up touch events | |
// | |
$.fn.addTouch = function() { | |
if ($.support.touch) { | |
this.each(function(i, el) { | |
el.addEventListener("touchstart", iPadTouchHandler, false); | |
el.addEventListener("touchmove", iPadTouchHandler, false); | |
el.addEventListener("touchend", iPadTouchHandler, false); | |
el.addEventListener("touchcancel", iPadTouchHandler, false); | |
}); | |
} | |
return this; | |
}; | |
}); | |
var lastTap = null; // Holds last tapped element (so we can compare for double tap) | |
var tapValid = false; // Are we still in the .6 second window where a double tap can occur | |
var tapTimeout = null; // The timeout reference | |
function cancelTap() { | |
tapValid = false; | |
} | |
var rightClickPending = false; // Is a right click still feasible | |
var rightClickEvent = null; // the original event | |
var holdTimeout = null; // timeout reference | |
var cancelMouseUp = false; // prevents a click from occuring as we want the context menu | |
function cancelHold() { | |
if (rightClickPending) { | |
window.clearTimeout(holdTimeout); | |
rightClickPending = false; | |
rightClickEvent = null; | |
} | |
} | |
function startHold(event) { | |
if (rightClickPending) | |
return; | |
rightClickPending = true; // We could be performing a right click | |
rightClickEvent = (event.changedTouches)[0]; | |
holdTimeout = window.setTimeout("doRightClick();", 800); | |
} | |
function doRightClick() { | |
rightClickPending = false; | |
// | |
// We need to mouse up (as we were down) | |
// | |
var first = rightClickEvent, | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 0, null); | |
first.target.dispatchEvent(simulatedEvent); | |
// | |
// emulate a right click | |
// | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 2, null); | |
first.target.dispatchEvent(simulatedEvent); | |
// | |
// Show a context menu | |
// | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent("contextmenu", true, true, window, 1, first.screenX + 50, first.screenY + 5, first.clientX + 50, first.clientY + 5, | |
false, false, false, false, 2, null); | |
first.target.dispatchEvent(simulatedEvent); | |
// | |
// Note:: I don't mouse up the right click here however feel free to add if required | |
// | |
cancelMouseUp = true; | |
rightClickEvent = null; // Release memory | |
} | |
// | |
// mouse over event then mouse down | |
// | |
function iPadTouchStart(event) { | |
var touches = event.changedTouches, | |
first = touches[0], | |
type = "mouseover", | |
simulatedEvent = document.createEvent("MouseEvent"); | |
// | |
// Mouse over first - I have live events attached on mouse over | |
// | |
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 0, null); | |
first.target.dispatchEvent(simulatedEvent); | |
type = "mousedown"; | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 0, null); | |
first.target.dispatchEvent(simulatedEvent); | |
if (!tapValid) { | |
lastTap = first.target; | |
tapValid = true; | |
tapTimeout = window.setTimeout(cancelTap, 600); | |
startHold(event); | |
} | |
else { | |
window.clearTimeout(tapTimeout); | |
// | |
// If a double tap is still a possibility and the elements are the same | |
// Then perform a double click | |
// | |
if (first.target == lastTap) { | |
lastTap = null; | |
tapValid = false; | |
type = "click"; | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 0/*left*/, null); | |
first.target.dispatchEvent(simulatedEvent); | |
type = "dblclick"; | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, 0/*left*/, null); | |
first.target.dispatchEvent(simulatedEvent); | |
} | |
else { | |
lastTap = first.target; | |
tapValid = true; | |
tapTimeout = window.setTimeout(cancelTap, 600); | |
startHold(event); | |
} | |
} | |
} | |
function iPadTouchHandler(event) { | |
var type = "", | |
button = 0; | |
/*left*/ | |
if (event.touches.length > 1) | |
return; | |
switch (event.type) { | |
case "touchstart": | |
if ($(event.changedTouches[0].target).is("select")) { | |
return; | |
} | |
iPadTouchStart(event); | |
/*We need to trigger two events here to support one touch drag and drop*/ | |
event.preventDefault(); | |
return false; | |
break; | |
case "touchmove": | |
cancelHold(); | |
type = "mousemove"; | |
event.preventDefault(); | |
break; | |
case "touchend": | |
if (cancelMouseUp) { | |
cancelMouseUp = false; | |
event.preventDefault(); | |
return false; | |
} | |
cancelHold(); | |
type = "mouseup"; | |
break; | |
default: | |
return; | |
} | |
var touches = event.changedTouches, | |
first = touches[0], | |
simulatedEvent = document.createEvent("MouseEvent"); | |
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, button, null); | |
first.target.dispatchEvent(simulatedEvent); | |
if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipads default behaviour (which we prevented) | |
simulatedEvent = document.createEvent("MouseEvent"); // This check avoids click being emulated on a double tap | |
simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, | |
false, false, false, false, button, null); | |
first.target.dispatchEvent(simulatedEvent); | |
} | |
} | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment