Subversion-Projekte lars-tiefland.ci

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
875 lars 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
* Modified: 19/01/2012
11
* Organized as a proper plugin and added addTouch()
12
*/
13
(function ($) {
14
	var lastTap = null,				// Holds last tapped element (so we can compare for double tap)
15
		tapValid = false,			// Are we still in the .6 second window where a double tap can occur
16
		tapTimeout = null,			// The timeout reference
17
		rightClickPending = false,	// Is a right click still feasible
18
		rightClickEvent = null,		// the original event
19
		holdTimeout = null,			// timeout reference
20
		cancelMouseUp = false,		// prevents a click from occurring as we want the context menu
21
		currentDOMElement = null;	// the last DOM element that was seen during a drag.
22
 
23
	function cancelTap() {
24
		tapValid = false;
25
	}
26
 
27
	function cancelHold() {
28
		if (rightClickPending) {
29
			window.clearTimeout(holdTimeout);
30
			rightClickPending = false;
31
			rightClickEvent = null;
32
		}
33
	}
34
 
35
	function startHold(event) {
36
		if (rightClickPending) {
37
			return;
38
		}
39
		rightClickPending = true; // We could be performing a right click
40
		rightClickEvent = (event.changedTouches)[0];
41
		holdTimeout = window.setTimeout(doRightClick, 800);
42
	}
43
 
44
	function doRightClick() {
45
		rightClickPending = false;
46
		// We need to mouse up (as we were down)
47
		var first = rightClickEvent,
48
			simulatedEvent = document.createEvent("MouseEvent");
49
		simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
50
		first.target.dispatchEvent(simulatedEvent);
51
 
52
		// Emulate a right click
53
		simulatedEvent = document.createEvent("MouseEvent");
54
		simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 2, null);
55
		first.target.dispatchEvent(simulatedEvent);
56
 
57
		// Show a context menu
58
		simulatedEvent = document.createEvent("MouseEvent");
59
		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);
60
		first.target.dispatchEvent(simulatedEvent);
61
 
62
		simulatedEvent = document.createEvent("MouseEvent");
63
		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);
64
		first.target.dispatchEvent(simulatedEvent);
65
 
66
		cancelMouseUp = true;
67
		rightClickEvent = null; // Release memory
68
	}
69
 
70
 
71
	// mouse over event then mouse down
72
	function iPadTouchStart(event) {
73
		var touches = event.changedTouches,
74
			first = touches[0],
75
			type = "mouseover",
76
			simulatedEvent = document.createEvent("MouseEvent");
77
 
78
		// Mouse over first - I have live events attached on mouse over
79
		simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
80
		first.target.dispatchEvent(simulatedEvent);
81
 
82
		type = "mousedown";
83
		simulatedEvent = document.createEvent("MouseEvent");
84
 
85
		simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
86
		first.target.dispatchEvent(simulatedEvent);
87
 
88
		if (!tapValid) {
89
			lastTap = first.target;
90
			tapValid = true;
91
			tapTimeout = window.setTimeout(cancelTap, 600);
92
			startHold(event);
93
		} else {
94
			window.clearTimeout(tapTimeout);
95
			// If a double tap is still a possibility and the elements are the same then perform a double click
96
			if (first.target == lastTap) {
97
				lastTap = null;
98
				tapValid = false;
99
 
100
				type = "click";
101
				simulatedEvent = document.createEvent("MouseEvent");
102
 
103
				simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
104
				first.target.dispatchEvent(simulatedEvent);
105
 
106
				type = "dblclick";
107
				simulatedEvent = document.createEvent("MouseEvent");
108
 
109
				simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
110
				first.target.dispatchEvent(simulatedEvent);
111
			} else {
112
				lastTap = first.target;
113
				tapValid = true;
114
				tapTimeout = window.setTimeout(cancelTap, 600);
115
				startHold(event);
116
			}
117
		}
118
	}
119
 
120
	function getDOMElementFromEvent(event) {
121
		if (event.targetTouches && event.targetTouches[0]) {
122
			return document.elementFromPoint(event.targetTouches[0].pageX - window.pageXOffset, event.targetTouches[0].pageY - window.pageYOffset);
123
		}
124
		return null;
125
	}
126
 
127
	function iPadTouchHandler(event) {
128
		var type = "",
129
			button = 0; /*left*/
130
		if (event.touches.length > 1) {
131
			return;
132
		}
133
		switch (event.type) {
134
		case "touchstart":
135
			if ($(event.changedTouches[0].target).is("select")) {
136
				return;
137
			}
138
			iPadTouchStart(event); /*We need to trigger two events here to support one touch drag and drop*/
139
			event.preventDefault();
140
			currentDOMElement = getDOMElementFromEvent(event);
141
			return false;
142
 
143
		case "touchmove":
144
			cancelHold();
145
			type = "mousemove";
146
			event.preventDefault();
147
 
148
			currentDOMElement = getDOMElementFromEvent(event);
149
			break;
150
 
151
		case "touchend":
152
			if (cancelMouseUp) {
153
				cancelMouseUp = false;
154
				event.preventDefault();
155
				return false;
156
			}
157
			cancelHold();
158
			type = "mouseup";
159
			break;
160
 
161
		default:
162
			return;
163
		}
164
		var touches = event.changedTouches,
165
			first = touches[0],
166
			simulatedEvent = document.createEvent("MouseEvent");
167
		simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,false, false, false, false, button, null);
168
		currentDOMElement.dispatchEvent(simulatedEvent);
169
		if (type == "mouseup" && tapValid && first.target == lastTap) {	// This actually emulates the ipad's default behavior (which we prevented)
170
			simulatedEvent = document.createEvent("MouseEvent");		// This check avoids click being emulated on a double tap
171
			simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,false, false, false, false, button, null);
172
			currentDOMElement.dispatchEvent(simulatedEvent);
173
		}
174
	}
175
 
176
	$.extend($.support, {
177
		touch: "ontouchend" in document
178
	});
179
 
180
	$.fn.addTouch = function () {
181
		if ($.support.touch) {
182
			this.each(function (i, el) {
183
				el.addEventListener("touchstart", iPadTouchHandler, false);
184
				el.addEventListener("touchmove", iPadTouchHandler, false);
185
				el.addEventListener("touchend", iPadTouchHandler, false);
186
				el.addEventListener("touchcancel", iPadTouchHandler, false);
187
			});
188
		}
189
		return this;
190
	};
191
 
192
})(jQuery);