touchend事件在Android上不起作用

时间:2010-06-07 07:23:19

标签: javascript android events touch

我刚刚开始考虑在Android上进行一些基本的移动Web开发,并编写测试脚本来调查触摸事件。我在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 个答案:

答案 0 :(得分:31)

对于任何试图找出Android v3和v4(也许还有v2.3)上缺少touchend事件的人来说,有一个长期未解决的错误,只是在v4.1(显然)中得到修复:

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

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

要解决此错误,您必须在touchstart或first touchmove事件上调用preventDefault()。当然,这会阻止本机滚动,因此您需要自己重新实现。

答案 1 :(得分:19)

这是你需要正确使用它的方法。当手指进入屏幕时,您捕获起始x,y。当手指移过时,touchmove事件更新结尾x,y。完成后,touchend会触发 - 但是,它没有触摸数组,因而出现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);

答案 2 :(得分:7)

这是网络开发,所以我正在构建一个可以利用触摸事件的网页。

我弄清楚问题是什么。

touchend事件被触发时,event.touches[]数组为空,因此抛出了Javascript错误。该事件被解雇,但它没有打印任何内容,因为我试图访问未定义的数据。模拟器浏览器似乎没有我找到的任何Javascript调试工具,甚至没有告诉我何时发生Javascript错误,所以我花了一段时间才弄明白。

答案 3 :(得分:2)

触发touchend事件时TouchList始终为空,因为你从屏幕上删除了所有手指:)。

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

答案 4 :(得分:2)

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

答案 5 :(得分:2)

我遇到了同样的问题,另外还绑定了触摸屏&#39;事件解决了它。进行了一些测试以及什么时候进行了测试&#39;没有解雇,然后触摸&#39;触摸&#39;事件被解雇了。

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

答案 6 :(得分:1)

这发生在KitKat上,并通过根据android dev http://developer.android.com/guide/webapps/migrating.html#TouchCancel

处理touchcancel来解决

对于较旧的Android版本,问题是由于如果不对touchstart事件应用preventdefault,则没有将触摸事件传递给webview。这被硬编码到数百万的Android设备中。 https://github.com/TNT-RoX/android-swipe-shim

答案 7 :(得分:1)

我能够通过从包含WebView的活动的touchend动作事件手动触发ACTION_UP事件来解决问题,如下所示:

//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;
   }
});

答案 8 :(得分:0)

这是一个启用滚动功能的解决方案:

在touchMove处理程序中添加preventDefault(),但将其包装在检查横向滚动移动的条件中:

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()
  }
}