我在使用Android Studio将一个html文件打包成一个apk,使用webview运行。
因为是要做一个简单的小游戏,所以需要用到触屏的操控,于是我使用了事件touchstart,touchend,touchmove来获取玩家点击的相关信息。
但在屏幕边缘处,事件touchend的触发有明显的问题。
正常来说,正常人在手机屏幕上进行一次快速的点击,touchstart和touchend的触发间隔相差50到100ms左右。
我使用touchend中event对象的时间戳减去touchstart的中event对象的时间戳,验证了这个结论,我点击一次手机屏幕后这两个时间戳的差值是60到80ms,这是正常的。
但当我点击屏幕的边缘处时,这两个时间戳的差值是0到3ms,这很明显不对,如果touchstart是正常触发的,那么touchend触发就过早了。
即使我触摸后瞬间抬起,或者触摸后突然将手指略微移动到可触摸范围外(touchmove也没触发),那也不可能这么短,肯定是有什么问题。
这是示例图:
其中灰色和红色部分合起来是游戏的显示区域,蓝色部分是前置摄像头,红色部分就是点击时touchend触发就过早的边缘处。
红色部分分为三部分,一是最上面和最下面的一定像素内,这一部分和手机是曲面屏无关,且当我触摸的时候,既然能触发touchstart,那么当我手指还没有抬起的时候不应该
触发touchend才对。而右方的红色部分似乎就是导航键所在的区域,但程序在运行时导航键已被隐藏,不应该是导航键的问题。
这是我测试时使用的简单html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"/>
</head>
<body style="background-color: black">
<canvas width="800" height="600" id="test"> </canvas>
<script type="text/javascript">
var canvasForTest = document.getElementById('test');
var contextForTest = canvasForTest.getContext('2d')
var touchstartTimestamp = 0;
window.addEventListener('touchstart', (e)=>{
touchstartTimestamp = e.timeStamp;
console.log("start");
});
window.addEventListener('touchend', (e)=>{
contextForTest.clearRect(0,0,800,600);
contextForTest.fillStyle = "#ffffff";
contextForTest.font="48px Georgia";
let text = "时间间隔为"+Math.floor(e.timeStamp-touchstartTimestamp)+"ms"
let width = contextForTest.measureText(text).width;
contextForTest.fillText(text,(800-width)/2,(600-48*96/72)/2,800);
console.log("end",e.timeStamp-touchstartTimestamp);
});
window.addEventListener('touchmove', (e)=>{
console.log("move");
});
window.addEventListener('touchcancel', (e)=>{
console.log("cancel");
});
</script>
</body>
</html>
测试的手机型号有:
vivio的X50,honor的magic 3 pro。
我在网上查找答案,使用了许多办法,包括什么event.preventDefault()和event.stopPropagation()但都无关且无效,很可能也不是页面滚动(scroll)的问题。
我在想是不是Android Studio中java语句的问题,但我想尽量能在html文件中通过某些语句解决问题,或者能找到这个问题发生的原因。