我正在开发一个需要在多种设备上运行的移动网站。目前让我头疼的是黑莓手机。

我们需要同时支持键盘点击和触摸事件。

理想情况下,我会使用:

$thing.click(function(){...})

但我们遇到的问题是,一些黑莓设备从触摸到触发点击有一个非常恼人的延迟。

补救方法是使用touchstart:

$thing.bind('touchstart', function(event){...})

但是如何绑定两个事件,但只触发一个事件呢?对于键盘设备,我仍然需要click事件,但当然,如果我使用的是触摸设备,我不想让click事件触发。

一个额外的问题:有没有办法做到这一点,并额外适应那些甚至没有touchstart事件的浏览器?在研究中,看起来黑莓OS5不支持touchstart,因此也需要依赖于该浏览器的点击事件。

附录:

也许一个更全面的问题是:

使用jQuery,是否可能/建议使用相同的绑定同时处理触摸交互和鼠标交互?

理想情况下,答案是肯定的。如果不是,我确实有一些选择:

我们使用WURFL来获取设备信息,这样就可以创建我们自己的设备矩阵。根据设备的不同,我们将使用touchstart或click。 通过JS检测浏览器中的触摸支持(我需要做更多的研究,但这似乎是可行的)。

然而,还有一个问题:支持这两种功能的设备怎么办?我们支持的一些手机(即诺基亚和黑莓)既有触摸屏又有键盘。这让我又回到了最初的问题……有没有一种方法可以同时兼顾两者?


当前回答

我也在开发Android/iPad web应用,似乎只要使用“touchmove”就足以“移动组件”(不需要touchstart)。 通过禁用touchstart,你可以使用.click();从jQuery。它实际上在工作,因为它没有被touchstart重载。

最后,你可以binb .live("touchstart", function(e) {e.s stoppropagation ();});要让touchstart事件停止传播,living room需要单击()来触发。

这对我很管用。

其他回答

我不得不做一些类似的事情。下面是一个对我有用的简化版本。如果检测到触摸事件,则删除单击绑定。

$thing.on('touchstart click', function(event){
  if (event.type == "touchstart")
    $(this).off('click');

  //your code here
});

在我的例子中,点击事件被绑定到<a>元素,所以我必须删除点击绑定并重新绑定点击事件,这阻止了<a>元素的默认操作。

$thing.on('touchstart click', function(event){
  if (event.type == "touchstart")
    $(this).off('click').on('click', function(e){ e.preventDefault(); });

  //your code here
});

你可以使用一个计数器来代替超时:

var count = 0;
$thing.bind('touchstart click', function(){
  count++;
  if (count %2 == 0) { //count 2% gives the remaining counts when devided by 2
    // do something
  }

  return false
});

利用点击总是会在触摸事件之后发生的事实,以下是我在不使用超时或全局标志的情况下消除“幽灵点击”的方法。

$('#buttonId').on('touchstart click', function(event){
    if ($(this).data("already")) {
        $(this).data("already", false);
        return false;
    } else if (event.type == "touchstart") {
        $(this).data("already", true);
    }
    //your code here
});

基本上,只要在元素上触发ontouchstart事件,就会设置一个标记,然后在点击到来时删除(并忽略)。

我不确定这是否适用于所有浏览器和设备。 我使用谷歌Chrome和Safari iOS进行了测试。

$thing.on('click || touchend', function(e){

});

OR操作数应该只触发第一个事件(在桌面上应该是click,在iPhone上应该是touchend)。

只要加上return false;末尾的on(“点击touchstart”)事件函数可以解决这个问题。

$(this).on("click touchstart", function() {
  // Do things
  return false;
});

来自jQuery文档。on()

从事件处理程序返回false将自动调用event. stoppropagation()和event. preventdefault()。false值也可以作为function(){return false;}。