Sto provando a gestire un clic del pulsante. Il "pulsante" è un div personalizzato che può contenere anche bambini. La richiamata clic deve essere attivata quando l'utente ha fatto clic e rilasciato all'interno dell'elemento. Se l'utente fa clic all'interno e trascina e rilascia all'esterno, il gestore non deve attivarsi. Ho bisogno di farlo funzionare su desktop e mobile, quindi sto usando gli eventi mousedown/mouseup
e touchstart/touchend
.Come rilevare un evento touchend al di fuori di un elemento
ho bisogno di cambiare la classe pulsante da "premuto" a "normale", anche se l'utente rilascia al di fuori, quindi ho bisogno di aggiungere un listener per catturare l'evento rilasciando il documento:
var $myElement = $("#myelement"); //This is a div and can also contain children.
$myElement.on("mousedown touchstart", function(e){
$(this).addClass("pressed");
$(document).on("mouseup touchend", function listener(e){
$myElement.removeClass("pressed");
$(document).off("mouseup touchend", listener);
var $target = $(e.target);
if ($target.is($myElement) || $target.parents().is($myElement)){
//FIXME
alert("Inside!");
//do something here
return false;
} else {
//FIXME
alert("Outside!");
//let event bubble
}
});
return false;
});
E ' funziona bene con i clic, ma non funziona come previsto con gli eventi touch. Ho provato questo in Chrome per Android e quando si preme sopra l'elemento, quindi trascinando fuori, il "Inside!" l'avviso è mostrato.
Il problema è in questa condizione:
if ($target.is($myElement) || $target.parents().is($myElement)){
sto cercando di verificare se l'evento si è verificato in touchend
il pulsante o uno qualsiasi dei bambini. Se il pulsante non ha figli, quando fai clic su di esso e poi rilasciando all'esterno, la prima parte della clausola OR si risolve in true. Se il pulsante ha figli e faccio clic sui bambini, quindi rilasciamo in qualsiasi altra parte dello schermo, la seconda parte della clausola è vera.
Cosa c'è di sbagliato con questo codice?
Grazie in anticipo.
UPDATE
L'ho provato anche in BlackBerry 10 con gli stessi risultati. Apparentemente l'obiettivo per l'evento touchend
è il pulsante (oi figli), anche quando ho fatto clic all'esterno. È così che dovrebbe funzionare?
UPDATE
Ed ecco perché. Questo è what the W3C docs say about the event:
L'obiettivo di questo evento deve essere lo stesso elemento che ha ricevuto l'evento TouchStart quando questo punto di contatto è disposto sulla superficie, anche se il punto di contatto è poi trasferito fuori area interattiva del elemento bersaglio.
Non ha senso per me, ma in ogni caso questo spiega il mio problema. Supponevo che l'evento touchend
sarebbe stato chiamato sull'elemento in cui è stato rilasciato il dito. Sarebbe possibile rilevare il rilascio delle dita all'esterno utilizzando un approccio diverso?
UPDATE
Ho cercato di ottenere le coordinate della touchevent
per ottenere l'elemento di là usando document.elementFromPoint
. Il problema è che questo evento non contiene le coordinate (gli elenchi changedTouches
e touches
sono vuoti). Ho esaminato attentamente l'evento nel debugger e non c'è modo di recuperarne altri da quelli dell'evento originale. Poi ho pensato che potevo memorizzare l'ultimo evento touchmove
e ottenere le corde da lì, ma ancora una volta questo evento non ha le proprie coordinate! Perché sulla Terra esistono questi due eventi quando sono inutili? E ho testato questo approccio su iOS, Android e BB10 con risultati identici.
Mi sono arreso. Chiamerò la richiamata anche se l'utente ha fatto clic all'esterno.Non posso credere che siano ragazzi del 2013 e non c'è un modo (semplice) per farlo? Potrei usare il drag & drop api ma in base a this non è supportato su dispositivi mobili (Gotta love mobile web development).
Anche se potrebbe non essere di aiuto, ho creato uno script VanillaJS che fa praticamente la stessa cosa e ha pubblicato una versione semplificata di quel codice [qui] (http://stackoverflow.com/questions/13030210/onclick-event-is-occuring-due-times-in-iphone-hybrid-app/13030622 # 13030622) –
@EliasVanOotegem grazie, ho letto su di esso, ma non ho potuto ancora provarlo. Sto leggendo la fonte di alcune delle librerie che hai collegato. Forse sto cercando di reinventare la ruota qui. –