123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /**
- * 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);
|