it-swarm.com.de

touchend-Ereignis funktioniert nicht auf Android

Ich habe gerade angefangen, einige grundlegende mobile Webentwicklungen für Android zu erstellen und ein Testskript zu schreiben, um die Berührungsereignisse zu untersuchen. Ich habe den folgenden Code im Android-Emulator ausgeführt, und das Touchend-Ereignis wird nie ausgelöst. Kann mir jemand sagen warum? 

Ich habe es in drei Versionen des Emulators (1.6, 2.1 und 2.2) probiert und alle drei verhalten sich gleich.

Vielen Dank im Voraus für jede Hilfe, die Sie mir geben können.

Cheers, Colm

EDIT - Ich habe es auch mit dem XUI-Framework ausprobiert und habe das gleiche Problem. Ich vermute, ich habe ein grundlegendes Missverständnis darüber, wie dieses Zeug funktioniert ......

Kartentest

    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <meta name="language" content="english" />

    <meta name="viewport" content="minimum-scale=1.0,
                                   width=device-width,
                                   height=device-height,
                                   user-scalable=no">
    <script type="text/javascript">
        window.onload = function(){
            document.body.appendChild(
                    document.createTextNode("w: " + screen.width + " x " + "h : " +screen.height)
            );
           attachTouchEvents();
        }
        function attachTouchEvents() {
            console = document.getElementById("console");
            var map = document.getElementById("map");
            map.addEventListener ('touchstart', function (event) {
                event.preventDefault();
                var touch = event.touches[0];
                document.getElementById("touchCoord").innerHTML = "S : " + touch.pageX + " " + touch.pageY;
                document.getElementById("touchEvent").innerHTML = "Touch Start";
            }, false);

            map.addEventListener ('touchmove', function (event) {
                event.preventDefault();
                var touch = event.touches[0];
                document.getElementById("touchCoord").innerHTML = "M : " + touch.pageX + " " + touch.pageY;
                document.getElementById("touchEvent").innerHTML = "Touch Move";
            }, false);

            map.addEventListener ('touchend', function (event) {
                var touch = event.touches[0];
                document.getElementById("touchCoord").innerHTML = "E : " + touch.pageX + " " + touch.pageY;
                document.getElementById("touchEvent").innerHTML = "Touch End";
                event.preventDefault();
            }, false);
            console.innerHTML = "event attached";
        }
    </script>
    <style type="text/css">
        html, body {
            height:100%;
            width:100%;
            margin: 0;
            background-color:red;
        }
        #map {
            height: 300px;
            width: 300px;
            background-color:yellow;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <div id="touchCoord">Touch Coords</div>
    <div id="touchEvent">Touch Evnt</div>
    <div id="console">Console</div>

</body>

32
Protos

Für jeden, der herauszufinden versucht, warum Touchend-Ereignisse auf Android v3 und v4 (möglicherweise auch v2.3) fehlen, gibt es einen langen, ausstehenden Fehler, der gerade in v4.1 (anscheinend) behoben wurde:

http://code.google.com/p/Android/issues/detail?id=4549

http://code.google.com/p/Android/issues/detail?id=19827

Um diesen Fehler zu beheben, müssen Sie preventDefault() entweder beim Touchstart- oder beim ersten Touchmove-Ereignis aufrufen. Dies verhindert natürlich das native Scrollen, so dass Sie das selbst neu implementieren müssen.

31
SystemParadox

So müssen Sie es richtig einsetzen. Sie erfassen das Start x, y, wenn der Finger zum Bildschirm geht. Wenn sich der Finger darüber bewegt, aktualisiert das Touchmove-Ereignis ein Ende x, y. Wenn der Vorgang abgeschlossen ist, wird das Touchend ausgelöst - aber es gibt kein Touch-Array und somit einen Javascript-Fehler. Deshalb verwenden wir es nur, um festzuhalten, dass dies eine Endaufgabe ist (Finger haben den Bildschirm verlassen) und reagieren darauf. (In diesem Fall sende ich eine informative Benachrichtigung.)

var gnStartX = 0;
var gnStartY = 0;
var gnEndX = 0;
var gnEndY = 0;

window.addEventListener('touchstart',function(event) {
  gnStartX = event.touches[0].pageX;
  gnStartY = event.touches[0].pageY;
},false);

window.addEventListener('touchmove',function(event) {
  gnEndX = event.touches[0].pageX;
  gnEndY = event.touches[0].pageY;
},false);

window.addEventListener('touchend',function(event) {
  alert('START (' + gnStartX + ', ' + gnStartY + ')   END (' + gnEndX + ', ' + gnEndY + ')');
},false);
19
Volomike

Es ist eine Webentwicklung, also baue ich eine Webseite, die die Touch-Ereignisse nutzen kann.

Ich habe herausgefunden, was das Problem war.

Wenn das touchend-Ereignis ausgelöst wird, ist das event.touches[]-Array leer, sodass ein Javascript-Fehler ausgegeben wird. Das Ereignis wurde ausgelöst, aber es wurde nichts gedruckt, da ich versuchte, auf undefinierte Daten zuzugreifen. Der Emulator-Browser scheint keine Javascript-Debugging-Tools zu haben, die ich gefunden habe, und hat mir nicht einmal mitgeteilt, wann ein Javascript-Fehler aufgetreten ist. Ich habe also eine Weile gebraucht, um das herauszufinden.

7
Protos
map.addEventListener ('touchend', function (event) {
    var touch = event.changeTouches[0];
    ...
}
2
kenshou.html

Ich hatte das gleiche Problem und zusätzlich wurde das 'touchcancel'-Event durch das Binden gelöst. Haben einige Tests durchgeführt und als 'touchend' nicht ausgelöst wurde, wurde stattdessen das 'touchcancel' -Ereignis ausgelöst.

var onTouchEnd = function(){
  console.log("touch end");
}
document.addEventListener("touchend", onTouchEnd);
document.addEventListener("touchcancel", onTouchEnd);
2

Die TouchList ist immer leer, wenn das Touchend-Ereignis ausgelöst wird, weil Sie alle Finger vom Bildschirm genommen haben :).

http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/

2
dplehati

Dies tritt bei KitKat auf und wird durch die Handhabung von Touchcancel gemäß Android dev http://developer.Android.com/guide/webapps/migrating.html#TouchCancel behoben.

Bei älteren Android-Versionen wird das Problem dadurch verursacht, dass Android keine Berührungsereignisse an Webview weiterleitet, wenn die Vorfalldefaultvorgabe nicht auf das Berührungsstartereignis angewendet wird. Dies ist in Millionen von Android-Geräten fest codiert. https://github.com/TNT-RoX/Android-swipe-shim

1
tnt-rox

Ich konnte das Problem beheben, indem ich das Ereignis touchend manuell für das Ereignis ACTION_UP motion aus der Aktivität auslöste, die das WebView wie folgt enthält:

//onCreate method
webView.setOnTouchListener(new View.OnTouchListener() 
{
   @Override
   public boolean onTouch(View view, MotionEvent motionEvent) 
   {
      if(motionEvent.getAction() == MotionEvent.ACTION_UP) 
      {
         webView.loadUrl("javascript:document.dispatchEvent(new CustomEvent('touchend'))");
      }
      return false;
   }
});
1
Petr Peller

Hier eine Lösung, um das Scrollen aktiviert zu halten:

Fügen Sie im touchMove-Handler eine preventDefault() hinzu, umschließen Sie sie jedoch mit einer Bedingung, die die seitliche Bildlaufbewegung überprüft:

onTouchStart = function (e) {                // Save start position
  startX = e.originalEvent.touches[0].pageX;
  startY = e.originalEvent.touches[0].pageY;
}

onTouchMove = function (e) {
  currentX = e.originalEvent.touches[0].pageX;
  currentY = e.originalEvent.touches[0].pageY;
  translateY = Math.abs(currentY - startY);
  if (translateY < 10) {   // If we are not (yet) scrolling vertically:
    e.preventDefault()
  }
}
0
Raymundus