- 短暂地在整个屏幕上显示橙色边框和高亮,并且
- 发送给我错误的事件。
以下是我迄今为止解决的所有痛苦细节。 这里是一个显示问题并显示有关接收到的每个事件的详细信息和时间的页面。如果您在蓝色矩形内轻敲,然后快速在黑色矩形内轻敲,您肯定会看到橙色闪光/错误事件。
我的jQuery代码非常标准。
log
函数的实现并不重要;问题在于浏览器没有在应该调用它时调用它。el = $('#battle');
el.on('touchstart', function(event) {
log(event);
return event.preventDefault();
});
el.on('touchend', function(event) {
return log(event);
});
el.on('touchcancel', function(event) {
return log(event);
});
el.mousedown(function(event) {
log(event);
return event.preventDefault();
});
return el.mouseup(function(event) {
return log(event);
});
关于我最初描述的现象的更多细节:
橙色边框和高亮:这是浏览器在单击超链接时绘制的相同橙色边框和高亮。但页面上没有超链接,浏览器会在整个屏幕周围--或更具体地说,在我通过jQuery挂钩事件的外部<div id="battle">
周围绘制这个橙色边框。
错误的事件:在我的touchstart
事件处理程序中,我调用了event.preventDefault()
,告诉浏览器不要滚动、不要合成鼠标事件等等。因此,我只期望得到touchstart
和touchend
事件。对于第一次轻拍,我确实得到了这些事件。但是对于第二次轻拍,我得到了所有数量的组合的触摸事件、合成的鼠标事件,以及偶尔的touchcancel
,甚至是第一次轻拍的重复事件。详情见下文。
这种行为也只发生在非常特定的情况下:
- 第一次轻拍必须很短(小于约200毫秒)。
- 第二次轻拍必须紧随其后(在第一次
touchstart
后不到约450毫秒)。 - 第二次轻拍必须与第一次轻拍的坐标相距至少150像素(沿第一次
touchstart
的对角线测量)。 - 如果我删除挂钩
mousedown
和mouseup
的代码,则橙色矩形不再出现。但是触摸事件有时仍然混乱。
至于我所说的事件混乱是什么意思,这是我看到的情况。当我写“1:”时,表示事件是为第一次轻拍的坐标;“2:”表示第二次轻拍的坐标。我看到了以下事件模式(百分比表示每个事件在100次试验中出现的次数):
- (50%) 1:touchstart 1:touchend 1:mousedown 1:mouseup(短暂延迟)2:mousedown 2:mouseup
- (35%) 1:touchstart 1:touchend 2:touchstart 1:mousedown 1:mouseup 2:touchend
- (10%) 1:touchstart 1:touchend 2:touchstart 1:mousedown 1:mouseup 2:touchcancel(短暂延迟)2:mousedown 2:mouseup
- (3%) 1:touchstart 1:touchend 2:touchstart 2:touchend(短暂延迟)1:mousedown 1:mouseup
- (2%) 1:touchstart 1:touchend 1:mousedown 1:mouseup (第二次轻拍根本没有任何事件)
如果我不挂钩mousedown
和mouseup
,分布大致如下:
- (40%) 1:touchstart 1:touchend 2:touchstart 2:touchcancel
- (35%) 1:touchstart 1:touchend 2:touchstart 2:touchend (实际期望的行为)
- (25%) 1:touchstart 1:touchend (第二次轻敲没有反应)
因此,如果我不挂钩鼠标事件,则它将有三分之一的成功率;如果我愿意假装touchcancel
和touchend
的含义相同,我可以将其提高到75%。但这仍然很糟糕。
我已经尝试过的替代方法:
- 我尝试使用jQuery Mobile的
vmousedown
和vmouseup
事件,但它们并不总是为第二次轻敲触发,我怀疑是由于这种潜在的事件异常。 - 我可能只需完全忘记触摸事件,并仅使用合成的鼠标事件,但物理轻敲和传递合成的鼠标事件之间通常会有约半秒钟的延迟,而触摸事件是即时的,因此我可以更具响应性。我还想防止滚动-这是一个全屏游戏,我宁愿不让用户意外滚动地址栏回到视图并阻挡游戏的一部分-在
touchstart
上执行preventDefault
通常可以实现这一点(尽管偶尔第二次轻敲实际上能够滚动屏幕,尽管我进行了preventDefault
…这就是我想解决整个事件混乱的原因之一)。 - 我尝试过第三方Web浏览器(Dolphin),但它也存在事件问题。因此,我猜测这可能是底层WebView将事件传递给脚本的方式存在问题。
有人能建议一种方法来更改我的HTML、事件处理程序或其他任何内容,以可靠地获取连续两次快速轻敲的触摸事件吗?