Próbuję obsłużyć kliknięcie przycisku. "Przycisk" to niestandardowy element div, który może również zawierać elementy podrzędne. Kliknięcie zwrotne powinno wystrzelić, gdy użytkownik kliknie i zwolni element wewnątrz elementu. Jeśli użytkownik kliknie w środku, a następnie przeciągnie i zwalnia na zewnątrz, przewodnik nie powinien strzelać. Muszę uruchomić to zarówno na komputerze stacjonarnym, jak i mobilnym, dlatego używam zdarzeń mousedown/mouseup
i touchstart/touchend
.Jak wykryć zdarzenie touchend poza elementem
muszę zmienić klasę przycisk z „wciśnięty” do „normalnego”, nawet jeśli użytkownik zwalnia na zewnątrz, więc trzeba dodać detektor uchwycić uwalniający imprezę nad dokumentem:
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;
});
It działa dobrze z kliknięciami, ale nie działa zgodnie z oczekiwaniami w przypadku zdarzeń dotykowych. Testowałem to w Chrome na Androida i naciskając na element, a następnie przeciągając, "Wewnątrz!" alert jest wyświetlany.
Problem jest w tym stanie:
if ($target.is($myElement) || $target.parents().is($myElement)){
Próbuję sprawdzić, czy zdarzenie wystąpiło w touchend
przycisku lub którykolwiek z dziećmi. Jeśli przycisk nie ma dzieci, po kliknięciu, a następnie zwolnieniu na zewnątrz, pierwsza część klauzuli OR staje się prawdą. Jeśli przycisk ma dzieci i klikam w dzieci, a następnie zwalniam w dowolnej innej części ekranu, druga część klauzuli jest prawdziwa.
Co jest nie tak z tym kodem?
Dzięki z góry.
AKTUALIZACJA
Testowałem to również w BlackBerry 10 z takimi samymi wynikami. Najwyraźniej celem zdarzenia touchend
jest przycisk (lub dzieci), nawet gdy kliknąłem na zewnątrz. Czy to ma działać?
UPDATE
A oto dlaczego. To what the W3C docs say about the event:
Celem tego wydarzenia musi być ten sam element, który otrzymał zdarzenie touchstart gdy punkt ten dotyk był umieszczony na powierzchni, nawet jeśli punkt dotykowy od tego czasu przeniósł się poza interaktywnej Powierzchnia element docelowy.
Nie ma dla mnie sensu, ale w każdym razie to wyjaśnia mój problem. Zakładałem, że zdarzenie o nazwie touchend
zostanie wywołane przez element, w którym palec został zwolniony. Czy byłoby możliwe wykrycie uwolnienia palca na zewnątrz przy użyciu innego podejścia?
UPDATE
Próbowałem dostać współrzędne touchevent
dostać się tam za pomocą elementu document.elementFromPoint
. Problem polega na tym, że to zdarzenie nie zawiera współrzędnych (listy changedTouches
isą puste). Dokładnie sprawdziłem zdarzenie w debugerze i nie ma sposobu na odzyskanie współrzędnych z niego innych niż oryginalne wydarzenie. Pomyślałem, że mogę zapisać ostatnie wydarzenie touchmove
i pobrać współrzędne, ale znowu to zdarzenie nie ma własnych współrzędnych! Dlaczego, na Boga, te dwa wydarzenia istnieją, gdy są bezużyteczne? I testowałem to podejście w iOS, Android i BB10 z identycznymi wynikami.
Poddałem się. Zadzwonię do oddzwonienia, nawet jeśli użytkownik kliknął na zewnątrz.Nie mogę uwierzyć, że to faceci z 2013 roku i nie ma (prostego) sposobu na zrobienie tego? Mógłbym użyć funkcji przeciągania & drop api, ale zgodnie z this jest ona nieobsługiwana na urządzeniach mobilnych (Uwielbiam rozwój aplikacji mobilnych).
Chociaż może to nie pomóc ci bezpośrednio, stworzyłem skrypt VanillaJS, który robi to samo i opublikował uproszczoną wersję tego kodu [tutaj] (http://stackoverflow.com/questions/13030210/onclick-event-is-occuring-two-times-in-iphone-hybrid-app/13030622 # 13030622) –
@EliasVanOotegem dzięki, przeczytałem go, ale nie mogłem go jeszcze przetestować. Teraz czytam źródło niektórych bibliotek, które połączyłeś. Może próbuję wymyślić tutaj koło. –