Fix for issue 1446 - Can't drag slider in 1.0a4.1 (Android 2.1)

- Don't bind and unbind our touch listeners dynamically. This gets Android 2.1 into a strange state where it stops dispatching touch events. Instead, we now register our touchmove, touchend and scroll listeners at the same time we register our permanent touchstart listener, we then block and unblock processing in our touch listeners via a flag.
This commit is contained in:
Kin Blas 2011-04-13 15:52:51 -07:00
parent 212f9ed237
commit 609d1de5f4

View file

@ -33,6 +33,7 @@ var dataPropertyName = "virtualMouseBindings",
didScroll = false,
clickBlockList = [],
blockMouseTriggers = false,
blockTouchTriggers = false,
eventCaptureSupported = $.support.eventCapture,
$document = $(document),
nextTouchID = 1,
@ -118,34 +119,12 @@ function getClosestElementWithVirtualBinding(element, eventType)
function enableTouchBindings()
{
if (!activeDocHandlers["touchbindings"]){
$document.bind("touchend", handleTouchEnd)
// On touch platforms, touching the screen and then dragging your finger
// causes the window content to scroll after some distance threshold is
// exceeded. On these platforms, a scroll prevents a click event from being
// dispatched, and on some platforms, even the touchend is suppressed. To
// mimic the suppression of the click event, we need to watch for a scroll
// event. Unfortunately, some platforms like iOS don't dispatch scroll
// events until *AFTER* the user lifts their finger (touchend). This means
// we need to watch both scroll and touchmove events to figure out whether
// or not a scroll happenens before the touchend event is fired.
.bind("touchmove", handleTouchMove)
.bind("scroll", handleScroll);
activeDocHandlers["touchbindings"] = 1;
}
blockTouchTriggers = false;
}
function disableTouchBindings()
{
if (activeDocHandlers["touchbindings"]){
$document.unbind("touchmove", handleTouchMove)
.unbind("touchend", handleTouchEnd)
.unbind("scroll", handleScroll);
activeDocHandlers["touchbindings"] = 0;
}
blockTouchTriggers = true;
}
function enableMouseBindings()
@ -232,6 +211,10 @@ function handleTouchStart(event)
function handleScroll(event)
{
if (blockTouchTriggers){
return;
}
if (!didScroll){
triggerVirtualEvent("vmousecancel", event, getVirtualBindingFlags(event.target));
}
@ -242,6 +225,10 @@ function handleScroll(event)
function handleTouchMove(event)
{
if (blockTouchTriggers){
return;
}
var t = getNativeEvent(event).touches[0];
var didCancel = didScroll,
@ -259,6 +246,10 @@ function handleTouchMove(event)
function handleTouchEnd(event)
{
if (blockTouchTriggers){
return;
}
disableTouchBindings();
var flags = getVirtualBindingFlags(event.target);
@ -339,7 +330,22 @@ function getSpecialEventObject(eventType)
activeDocHandlers["touchstart"] = (activeDocHandlers["touchstart"] || 0) + 1;
if (activeDocHandlers["touchstart"] === 1) {
$document.bind("touchstart", handleTouchStart);
$document.bind("touchstart", handleTouchStart)
.bind("touchend", handleTouchEnd)
// On touch platforms, touching the screen and then dragging your finger
// causes the window content to scroll after some distance threshold is
// exceeded. On these platforms, a scroll prevents a click event from being
// dispatched, and on some platforms, even the touchend is suppressed. To
// mimic the suppression of the click event, we need to watch for a scroll
// event. Unfortunately, some platforms like iOS don't dispatch scroll
// events until *AFTER* the user lifts their finger (touchend). This means
// we need to watch both scroll and touchmove events to figure out whether
// or not a scroll happenens before the touchend event is fired.
.bind("touchmove", handleTouchMove)
.bind("scroll", handleScroll);
}
}
},
@ -359,7 +365,10 @@ function getSpecialEventObject(eventType)
--activeDocHandlers["touchstart"];
if (!activeDocHandlers["touchstart"]) {
$document.unbind("touchstart", handleTouchStart);
$document.unbind("touchstart", handleTouchStart)
.unbind("touchmove", handleTouchMove)
.unbind("touchend", handleTouchEnd)
.unbind("scroll", handleScroll);
}
}