|
|
/** * 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/
* * Modified: 19/01/2012 * Organized as a proper plugin and added addTouch() */ (function ($) { var lastTap = null, // Holds last tapped element (so we can compare for double tap)
tapValid = false, // Are we still in the .6 second window where a double tap can occur
tapTimeout = null, // The timeout reference
rightClickPending = false, // Is a right click still feasible
rightClickEvent = null, // the original event
holdTimeout = null, // timeout reference
cancelMouseUp = false, // prevents a click from occurring as we want the context menu
currentDOMElement = null; // the last DOM element that was seen during a drag.
function cancelTap() { tapValid = false; } 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);
simulatedEvent = document.createEvent("MouseEvent"); simulatedEvent.initMouseEvent("mouseup", 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);
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, 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, null); first.target.dispatchEvent(simulatedEvent); } else { lastTap = first.target; tapValid = true; tapTimeout = window.setTimeout(cancelTap, 600); startHold(event); } } }
function getDOMElementFromEvent(event) { if (event.targetTouches && event.targetTouches[0]) { return document.elementFromPoint(event.targetTouches[0].pageX - window.pageXOffset, event.targetTouches[0].pageY - window.pageYOffset); } return null; }
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(); currentDOMElement = getDOMElementFromEvent(event); return false;
case "touchmove": cancelHold(); type = "mousemove"; event.preventDefault();
currentDOMElement = getDOMElementFromEvent(event); 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); currentDOMElement.dispatchEvent(simulatedEvent); if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipad's default behavior (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); currentDOMElement.dispatchEvent(simulatedEvent); } } $.extend($.support, { touch: "ontouchend" in document });
$.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; };
})(jQuery);
|