мероприятие touchend не работает на Android - PullRequest
32 голосов
/ 07 июня 2010

Я только начал изучать некоторые базовые разработки для мобильных устройств на Android и написание тестового сценария для изучения сенсорных событий. Я запустил следующий код в эмуляторе Android, и событие touchend никогда не запускается. Кто-нибудь может сказать мне, почему?

Я пробовал в трех версиях эмулятора (1.6, 2.1 и 2.2) и все три ведут себя одинаково.

Заранее спасибо за любую помощь, которую вы можете мне дать.

Ура, Колм

РЕДАКТИРОВАТЬ - Я также пробовал это с использованием инфраструктуры XUI и у меня та же проблема, поэтому я предполагаю, что у меня есть фундаментальное недопонимание того, как этот материал работает ......

Тест карты

    <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>

Ответы [ 9 ]

31 голосов
/ 23 июля 2012

Для тех, кто пытается выяснить, почему отсутствуют события касания в Android v3 и v4 (возможно, также v2.3), существует длинная выдающаяся ошибка, которая только что была исправлена ​​в v4.1 (очевидно):

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

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

Чтобы обойти эту ошибку, вы должны вызвать preventDefault() либо при запуске касанием, либо при первом событии касания.Конечно, это предотвращает собственную прокрутку, поэтому вам нужно будет повторно реализовать это самостоятельно.

19 голосов
/ 17 января 2011

Вот как вам нужно правильно его использовать.Вы захватываете начальные x, y, когда палец идет к экрану.Когда палец перемещается, событие touchmove обновляет окончание x, y.Когда закончено, запускается touchend - но да, у него нет массива touch, и, следовательно, ошибка JavaScript.Вот почему мы используем его только для того, чтобы зафиксировать, что это конечная задача (пальцы покинули экран), а затем реагируем на нее.(В этом случае я отправляю информационное оповещение.)

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);
7 голосов
/ 07 июня 2010

Это веб-разработка, поэтому я создаю веб-страницу, которая может использовать сенсорные события.

Я понял, в чем проблема.

При возникновении события touchend массив event.touches[] пуст, поэтому выдается ошибка Javascript. Событие было запущено, но ничего не распечатывалось, потому что я пытался получить доступ к неопределенным данным. Браузер эмулятора, похоже, не имеет каких-либо инструментов отладки Javascript, которые я нашел, и даже не сообщил мне, когда произошла ошибка Javascript, поэтому мне потребовалось некоторое время, чтобы выяснить это.

2 голосов
/ 23 мая 2016

У меня была та же проблема, и дополнительное связывание события 'touchcancel' решило ее.Провел некоторое тестирование, и когда «touchend» не был запущен, вместо этого сработало событие «touchcancel».

2 голосов
/ 29 марта 2012
map.addEventListener ('touchend', function (event) {
    var touch = event.changeTouches[0];
    ...
}
2 голосов
/ 03 июля 2010

TouchList всегда пуст, когда происходит событие касания, потому что вы убрали все пальцы с экрана:).

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

1 голос
/ 01 февраля 2015

Мне удалось устранить проблему, вызвав событие touchend вручную для события движения ACTION_UP из действия, содержащего WebView, следующим образом:

//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 голос
/ 06 августа 2014

Это происходит на KitKat и решается обработкой touchcancel в соответствии с android dev http://developer.android.com/guide/webapps/migrating.html#TouchCancel

В более старых версиях Android проблема вызвана тем, что android не передает события касания в веб-просмотр, если на событие touchstart не применяется предотвращение ошибок. Это жестко запрограммировано в миллионах устройств Android. https://github.com/TNT-RoX/android-swipe-shim

0 голосов
/ 17 мая 2017

Вот решение, позволяющее держать прокрутку включенной:

Добавьте preventDefault() в обработчик touchMove, но оберните его в условие, которое проверяет боковое движение прокрутки:

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()
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...