触发jQuery移动点击事件两次

时间:2012-05-29 06:34:55

标签: jquery jquery-mobile

我使用jquery移动'tap'事件进行了测试,发现它每次触发时都会解除两次。 html页面的代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>    
    <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js"></script>      
    <style>
        #box{
            background-color:red;
            width:200px;
            height:200px;
        }   
    </style>
</head>
<body>
    <div id="box">
        tapped me
    </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#box').bind('tap',function(event) {
                alert('why');
            }); 
        });
    </script>
</body>
</html>

更具讽刺意味的是,当我在jsfiddle上测试时,它只会在一次时触发事件。

这是链接。 http://jsfiddle.net/mochatony/tzQ6D/6/

经过进一步测试后,我发现将javascript放在标题部分已经消失了。

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">    
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
    </script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.js">
    </script>
    <style type="text/css">
        #box{ background-color:red; width:200px; height:200px; }
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#box').bind('tap', function(event) {
                alert('halo');
            });
        });
    </script>        
</head>
<body>
    <div id="box">
        tapped me
    </div>
</body>
</html>

我无法解释为什么身体和标题部分的位置会使它与众不同。

8 个答案:

答案 0 :(得分:15)

我忘了我在哪里看到这个,但问题是jQuery Mobile绑定到触摸和鼠标事件以模拟“点击”,在某些情况下Android会触发两者。

对我有用的技巧是在事件处理程序中对事件调用preventDefault。这样可以防止重复事件发生。

至于为什么只是有时这种情况,我知道如果有人没有收听触摸版本,移动浏览器将尝试仅触发事件的鼠标版本。检测或jQuery的委托可能存在一个问题,这会让启发式混淆。

答案 1 :(得分:9)

您遇到了鬼点击问题......这是一个已知的“错误”,很难解决。

那里有更多信息:

http://forum.jquery.com/topic/tap-fires-twice-with-live-tap https://developers.google.com/mobile/articles/fast_buttons http://philosopherdeveloper.wordpress.com/2011/11/01/ghost-clicks-in-jquery-mobile/

在第一个链接中,你会发现一个可以解决问题的黑客攻击。据我所知,没有简单的解决方案:(

顺便说一句:即使它不能解决你的问题,@ Sagiv也是对的。 JQuery mobile经常使用ajax来更改页面,因此不会触发document.ready事件。

答案 2 :(得分:5)

来自jQuery Mobile page

  

重要提示:使用$(document).bind('pageinit'),而非$(document).ready()
  你在jQuery中学到的第一件事就是在里面调用代码   $(document).ready()函数,所以一切都会尽快执行   DOM已加载。但是,在jQuery Mobile中,Ajax用于加载   导航时每个页面的内容都放入DOM中,并准备好DOM   处理程序仅对第一页执行。每当执行代码时   加载并创建新页面,您可以绑定到pageinit事件。   此事件在本页底部详细说明。

所以跳过$(document).ready()。更多信息here

答案 3 :(得分:2)

与这个问题有关,我正在接受两个活动,然后点击这个问题。并点击&#39;一个就在另一个之后。这里的所有想法都很鼓舞人心,但我最终找到了另一种解决方案。我将以下代码添加到我的JavaScript控制器,以根据时间戳区分连续的重复事件,幸运的是,两个重复事件完全相同。基本上,我做的是存储最后使用的时间戳,如果我决定使用该事件。第二次具有相同时间戳的事件我刚丢弃它。

&#13;
&#13;
var _lastEventTimestamp;
var checkAndPreventDuplicatedEvent = function (e) {
    if (e.timeStamp === _lastEventTimestamp) return true;
    else _lastEventTimestamp = e.timeStamp;
    return false;
}
&#13;
&#13;
&#13;

然后,在我的每个处理程序中,我在开头添加了这个过滤代码:

&#13;
&#13;
var onTapSomething = function (e) {
   if (checkAndPreventDuplicatedEvent(e)) return;        
   //do here whatever you would do in the case of legitimate event...   
}
&#13;
&#13;
&#13;

答案 4 :(得分:1)

$("#buttonID").tap(function(event){
        if(localStorage.JQMGostClick == 0 || localStorage.JQMGostClick == "" || typeof(localStorage.JQMGostClick) === "undefined")
            localStorage.JQMGostClick = 1;
        else if(localStorage.JQMGostClick == 1){
            localStorage.JQMGostClick = 0;
            return false;
        }
.....
});

它适用于我,因为如果您使用移动环境,那么可能您使用的是一种存储

答案 5 :(得分:0)

我发现在我的情况下,在我的页面容器中添加data-role="page"会阻止点击事件被触发两次。

答案 6 :(得分:0)

之前我经历过这样的事情,这是因为我的表格不在data-role="page"

我建议用jQuery Mobile html结构包装你的代码,这样你的内容应该是这样的

<div data-role="page" class="ui-page ui-page-theme-a ui-page-active">
  <div class="ui-content">
    <div id="box">
        tapped me
    </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#box').bind('tap',function(event) {
                alert('why');
            }); 
        });
    </script>
   </div>
</div>

答案 7 :(得分:0)

这可能不是最好的解决方案,只会在某些情况下起作用,但对我有用的是在点击事件开始后立即设置CSS&#39;指针 - 事件&#39;该元素为“无”#39;然后使用JS的setTimeout重置&#39;指针事件&#39; 500ms后自动播放。

对于我来说,Android设备足够300毫秒,但iPhone需要500毫秒才能防止双击。

&#13;
&#13;
function yourEvent(evt){

  $(el).css('pointer-events', 'none');
  
  setTimeout(function(){
      $(el).css('pointer-events', 'auto');
  }, 500);
  
  //do you stuff

}
&#13;
&#13;
&#13;