【问题标题】:jQuery mobile tap event triggered for twicejQuery 移动点击事件触发了两次
【发布时间】:2012-05-29 06:34:54
【问题描述】:

我使用 jquery mobile '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>

我无法解释为什么正文和标题部分的位置会有所不同。

【问题讨论】:

    标签: jquery jquery-mobile


    【解决方案1】:

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

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

    至于为什么只是有时会出现这种情况,我知道移动浏览器会尝试仅在有人不听触摸版本的情况下触发鼠标版本的事件。检测或 jQuery 的委派可能存在使启发式方法混淆的问题。

    【讨论】:

    • 在触发鼠标事件和触摸事件的情况下,结合 preventDefault 返回 false 应该可以在大多数(可能是所有)浏览器中修复它。
    • 是的,这似乎也对我们有用。我可以确认,在使用 jquery mobile 1.4.2 时,我们遇到了这种行为,并且设置 e.preventDefault() 为我们解决了这个问题。
    • 太棒了!就我而言,我将 e.preventDefault(); 放在$('.selector').on('click touchstart', function(e){}) 函数中的所有操作和魔术发生之后。 W/o e.preventDefault(); touchstart 事件导致双击/点击。非常感谢你,伙计!
    【解决方案2】:

    您遇到了重影点击问题...这是一个已知的“错误”并且难以解决。

    那里有更多信息:

    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/

    在第一个链接中,您会找到一个可以解决问题的 hack。据我所知,没有简单的解决方案:(

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

    【讨论】:

    • 感谢您的回复。如果我将代码放在标题部分,我发现问题就消失了。不知道为什么。
    【解决方案3】:

    来自jQuery Mobile page

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

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

    【讨论】:

    • 感谢您的回复。使用 pageinit 进行了测试,pageinit 事件也被触发了两次。我在 Firefox 和 chrome 上都进行了测试。我觉得很奇怪。
    【解决方案4】:

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

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

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

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

    【讨论】:

    • 另外,您可以使用相同的策略来消除一些“噪音”事件,以防万一。我在 android 上遇到了一些问题...我通过使用以前过滤器的修改版本摆脱了这些问题: var checkAndPreventDuplicatedEvent = function (e) { if ((e.timeStamp - _lastEventTimestamp)
    【解决方案5】:
    $("#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;
            }
    .....
    });
    

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        我之前经历过这样的事情,这是因为我的表单不在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>
        

        【讨论】:

          【解决方案8】:

          这可能不是最好的解决方案,并且仅在某些情况下有效,但对我有用的是在单击事件开始后立即将该元素的 CSS“指针事件”设置为“无”。然后使用 JS 的 setTimeout 在 500 毫秒后将“指针事件”重置为自动。

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-20
            • 1970-01-01
            相关资源
            最近更新 更多