The problem is that the JQMobile TAP event responds to/simulates both a touchEnd event (for mobile devices) and a click event (for desktop browsers). This is an attempt to have the same JQM code work whether the user is visiting the site from a mobile or desktop device.
Unfortunately, in the simulator and on many mobile devices, this triggers TWO events at the same X, Y coordinate: first a touchEnd event on the add button is fired; the add button hides itself and shows the cancel button; and then the cancel button receives the click event. (This has been tested and confirmed.) In a desktop browser, only one event is triggered (click), so there's no problem.
More about this "ghost click" problem can be found at
https://developers.google.com/mobile...s/fast_buttons.
If you'd like to confirm this for yourself, modify the todo.
js code
Code:
// Note the addition of the evt parameter
$('#add').tap(function( evt ) {
$('#main').append(evt.originalEvent.type + " in #add.tap<br>"); // debug
...
// and again, slightly further down...
$('#cancel').tap(function( evt ) {
$('#main').append(evt.originalEvent.type + " in #cancel.tap<br>"); // debug
...
Then compare loading todo.html in a Safari, mobile Safari, iOS simulator, etc. (you should see the same misbehavior on mobile and simulator devices as before).
I spotted a potential solution at
http://forum.jquery.com/topic/tap-fi...-with-live-tap posted by
the_new_mr. Their approach is to remember the timestamp of the last event and, if the next event follows too closely in time, ignore it. The proposed inter-event threshold is 800 milliseconds.
At the top of todo.
js, add
Code:
var lastTapTime;
function isJqmGhostClick() {
var threshold = 800; // milliseconds
var currTapTime = new Date().getTime();
if(lastTapTime == null || currTapTime > (lastTapTime + threshold)) {
lastTapTime = currTapTime;
return false;
}
else {
return true;
}
}
Then, add one line to the beginning of the #add.tap and #cancel.tap event callback functions:
Code:
$('#add').tap(function() {
if (isJqmGhostClick()) return;
...
$('#cancel').tap(function() {
if (isJqmGhostClick()) return;
...