Ich versuche JavaScript und jQuery zu verwenden, um Berührungsereignisse zu erfassen. Aber ich sehe ein sehr seltsames Verhalten im Webbrowser unter Android 2.3.2: Immer wenn ich auf den Bildschirm tippe und dann schnell irgendwo anders auf dem Bildschirm tippe, der Browser:
Der orange Rand scheint nur ein verwandtes Symptom des gleichen zugrunde liegenden Problems zu sein, also mache ich mir keine Sorgen darüber - es ist tatsächlich praktisch, um zu wissen, wann der Browser Dinge vermasselt. Was ich wirklich wissen möchte, ist wie kann ich immer die richtigen Berührungsereignisse für zwei schnelle Antippen erhalten? Ich glaube, wenn das Problem gelöst ist, wird der orange Rand ebenfalls verschwinden.
>Was folgt, sind all die schmerzhaften Details, die ich bisher erarbeitet habe.
Hier ist eine Seite, die das Problem zeigt und eine Menge diagnostischer Informationen über die Details und Details anzeigt Zeitpunkt jedes empfangenen Ereignisses. Sie werden sicher die orangefarbenen Flash- / Bad-Ereignisse erhalten, wenn Sie auf das blaue Rechteck tippen und dann schnell auf das schwarze Rechteck tippen.
Mein jQuery-Code ist ziemlich Standard. Die Implementierung von log
ist nicht wichtig. Das Problem ist, dass der Browser es nicht aufruft, wenn es sollte.
Weitere Details zu den eingangs beschriebenen Phänomenen:
Orange Rahmen und Hervorhebung: Dies ist der gleiche orange Rahmen und hebt hervor, dass der Browser einen Hyperlink umrahmt, wenn Sie darauf klicken. Aber es gibt keine Hyperlinks auf der Seite, und der Browser zeichnet diesen orangefarbenen Rahmen um den gesamten Bildschirm herum - oder genauer gesagt, um den äußeren <div id="battle">
, an den ich Ereignisse über jQuery anhänge.
Falsche Ereignisse: In meinem touchstart
Ereignishandler rufe ich event.preventDefault()
an, um dem Browser zu sagen, dass er nicht scrollt, Mausereignisse usw. nicht synthetisiert. Deshalb erwarte ich das Erhalten Sie nur touchstart
und touchend
Ereignisse. Und ich tue es, beim ersten Tippen. Aber anstatt touchstart
/ touchend
für den zweiten Tipp, erhalte ich eine ganze Anzahl von Kombinationen von Berührungsereignissen, synthetisierten Mausereignissen und gelegentlich touchcancel
für das zweite Tippen oder sogar wiederholte Ereignisse für das erste Tippen. Details unten.
Dieses Verhalten tritt auch nur unter ganz bestimmten Umständen auf:
touchstart
des ersten Tap). touchstart
des ersten Tap). mousedown
und mouseup
entferne, werden die orangefarbenen Rechtecke nicht mehr angezeigt. Die Berührungsereignisse sind jedoch manchmal immer noch verstümmelt. Soweit ich meine, dass die Ereignisse verstümmelt sind, hier ist, was ich sehe. Wenn ich "1:" schreibe, bedeutet das, dass die Ereignisse für die ersten Tap-Koordinaten sind; "2:" bedeutet die Koordinaten des zweiten Tap. Ich sah die folgenden Muster von Ereignissen (Prozentsätze zeigen an, wie oft jede nach 100 Versuchen auftauchte):
Einige Kombinationen von Ereignissen scheinen häufiger zu kommen, je nachdem, wie schnell ich tippe, aber ich habe das Muster noch nicht ganz durchnässt. (Zwei schnelle, scharfe Hähne scheinen eher unter dem zweiten Punkt oben zu erscheinen, während ein schnellerer Ansatz mit weniger Betonung der Knusprigkeit eher der erste Gegenstand ist. Aber ich habe keine spezifischen Timing-Zahlen identifiziert, die dazu führen zu jedem.) In ähnlicher Weise können die oben angegebenen "kurzen Verzögerungen" irgendwo zwischen ~ 150 ms und ~ 400 ms liegen; Ich habe das ganze Muster auch dort nicht rückentwickelt.
Wenn ich mousedown
und mouseup
nicht hake, ist die Verteilung grob wie folgt:
Wenn ich also die Mausereignisse nicht hake, funktioniert es ein Drittel der Zeit; und wenn ich bereit wäre vorzutäuschen, dass touchcancel
dasselbe bedeutet wie touchend
, könnte ich das bis zu 75% der Zeit bekommen. Aber das ist immer noch ziemlich sucky.
Alternativen, die ich schon versucht habe:
vmousedown
und vmouseup
-Ereignisse , aber sie werden nicht immer für den zweiten Tipp ausgelöst, ich vermute wegen der gleichen zugrunde liegenden Ereignis Seltsamkeit. preventDefault
auf touchstart
tut. erreicht dies normalerweise (obwohl gelegentlich das zweite Tippen tatsächlich den Bildschirm scrollen kann trotz meiner preventDefault
... ein anderer Grund, den ich dieses ganze Ereignischaos lösen möchte). Kann jemand vorschlagen, wie ich meinen HTML-Code, meine Event-Handler oder irgendetwas anderes ändern kann, um Touch-Ereignisse für zwei aufeinanderfolgende schnelle Antippen zuverlässig zu erhalten?
Nachdem ich versucht habe, Multi-Touch-HTML5-Spiele im Android-Browser zu entwickeln (und sie auch in anderen Android-kompatiblen Browsern auszuprobieren), denke ich, dass der Browser von Android 2.x die Berührungseingabe einfach nicht richtig unterstützt. Für den Anfang unterstützt es Multi-Touch nicht, was einige Arten von Spielen unspielbar macht. (Offensichtlich unterstützt das Telefon Multitouch, weil Sie zoomen können usw., aber der Browser nicht.) Dann gibt es viele Probleme mit Latenz, Berührungen ' und so weiter. Ich erinnere mich vage daran, dass ich etwas über die Treiber des Telefons für Touch-Eingaben gelesen habe, die nicht wirklich mit True Multitouch funktionieren (dh es kann entweder Single-Touch- oder Pinch-Zooms erkennen und das wars), aber ich habe keine Hinweise darauf, dass ich zurückkomme ... / p>
Anscheinend behebt Android 4 (Ice Cream Sandwich) es. Sie müssen also vielleicht nur auf Android 4 warten, das sowieso bald veröffentlicht werden sollte, und es erneut versuchen. Darüber hinaus haben Google angekündigt, den Android Browser in Zukunft durch eine mobile Version von Chrome zu ersetzen, sodass hoffentlich zumindest bis dahin unsere Touch-Eingabe-Probleme vorbei sind.
Das ist eine Theorie: Konnte nicht ausgiebig testen
Laut init Funktion im Quellcode einer Webview , wird die Anweisung setFocusable(true)
immer in einer Webansicht aufgerufen während seiner Initialisierung.
Als ich versuchte, die Ansicht nicht mehr fokussierbar zu machen, indem ich setFocusable(false)
verwendete, trat der Fehler nicht erneut auf. Es scheint, dass die orange Box nicht erscheint. Ich testete dies auf einem kleinen Samsung-Handy mit OS 2.3.4. Ich bin mir sicher, dass diese orange Box nicht wieder erscheint.
Falls sich herausstellt, dass dies wahr ist, ist es sehr wahrscheinlich, dass wir dies ohne unser eigenes Webview lösen können. Was die Dinge komplizierter macht, ist, wenn Sie die fokussierbare Eigenschaft auf false setzen, löst andere Probleme aus.
Schließlich glaube ich nicht, dass wir diese Eigenschaft von Javascript aus kontrollieren können (oder können wir?). Vielleicht können Sie deklarieren, dass ein bestimmtes Steuerelement oder das gesamte Dokument keine Eingabe oder etwas ähnliches ist? Ich extrapoliere nur so weit, dass dies falsch sein kann.
Bearbeiten: In Bezug auf Ihren Kommentar zu Ihrer Frage Ich habe gerade eine leere Anwendung mit nur einem Webview erstellt, die Ihre URL lädt, nachdem Sie ihre fokussierbare Eigenschaft auf false festgelegt haben. Bitte, wenn Sie mehr Ressourcen haben, um es zu testen, werde ich es für Sie hochladen, um es zu versuchen. Hier ist die Anwendung
Haben Sie versucht, die jQuery Mobile-Ereignisse zu verwenden? Die entkoppelten Widgets / Plugins finden Sie hier:
Sie werden wahrscheinlich jquery.mobile.event.js und jquery.mobile.vmouse.js
benötigenJetzt können Sie einfach die Ereignisse in jQuery mit dem Tap, Swipe usw. verknüpfen. Oder muss zwischen Anfang und Ende eines Tap unterschieden werden?
Haben Sie versucht, das Ereignis direkt anzuhängen?
%Vor%(Sorry, wenn der Code wirklich schlampig ist, habe ich der Log-Funktion nicht wirklich viel Aufmerksamkeit geschenkt, aber ich habe kleinere Änderungen vorgenommen, da er bei meinem touchend-Event nicht korrekt als event.touches [0 ] .pageX ist zu diesem Zeitpunkt undefiniert. Auch habe ich es in eine fertige Funktion eingepackt, weil ich nur faul war :-P)
Da dies nur die erste Berührung verfolgt (event.touches [0]), können Sie wahrscheinlich einige Einstellungen vornehmen, um Multi-Touch zu testen, indem Sie das Touch-Array nach unten gehen. Was ich auf meinem Android-Gerät (Lebkuchen) entdeckt habe, ist, dass wenn du zwei Finger gleichzeitig auf dem Bildschirm hast, das Touchend-Ereignis nur ausgelöst wird, wenn die letzte Berührung losgelassen wird; d.h. die zweite Fingerfreigabe.
Wenn ich die mouseup / mouseup Event-Listener angeschlossen habe, dann habe ich genau das Gleiche mit dem ganzen orangefarbenen Highlight-Ding gemacht.
Das Gerät, das ich getestet habe, war ein Samsung Droid Charge mit OTA Gingerbread Update.
Tags und Links javascript android jquery touchstart