【问题标题】:Phonegap 2.4.0 with Android 4.2 - strange double click behaviourPhonegap 2.4.0 与 Android 4.2 - 奇怪的双击行为
【发布时间】:2014-11-10 22:53:01
【问题描述】:

我正在使用 phonegap 2.4.0 创建一个 Android 和 iOS 应用程序。

现在我认识到,链接中的 onclick 事件在 Nexus 4 设备上使用 Android 4.2.2 的 Android 应用程序内触发了两次,就像双击一样(尽管我只点击了一次!)。

<a href="#" onclick="$(this).append('test'); return false;" style="some styles...">some text</a>

正在使用的库:

  • jQuery 1.9.1
  • jquery mobile 1.3.0 (rc)
  • jquery ui 1.10.0
  • jquery touch punch 0.2.2
  • phonegap 2.4.0

在我点击(或点击)我的 Nexus 4(Android 4.2.2)上的链接后,字符串“test”会在应用程序内附加两次。

当我直接在 android 浏览器中将其作为移动网络应用程序进行测试时,不会发生这种情况。

它也适用于应用程序内的我的三星 S3 (Android 4.1.2)。 iPhone 上也没有问题。

还有其他人认识到这种奇怪的行为吗? (也许能够修复它?;-))

【问题讨论】:

    标签: android cordova onclick double-click


    【解决方案1】:

    使用来自scirra.com 的临时解决方案

    last_click_time = new Date().getTime();
    document.addEventListener('click', function (e) {
        click_time = e['timeStamp'];
        if (click_time && (click_time - last_click_time) < 1000) {
            e.stopImmediatePropagation();
            e.preventDefault();
            return false;
        }
        last_click_time = click_time;
    }, true);
    

    【讨论】:

    • 我已经实现了同一个 hack 的多个版本,这个很漂亮 - 不知道为什么我从来没有在文档点击级别解决它,感谢重新分享 :)
    • 很好的解决方案,我遇到了一个小故障,因为如果检测到“幽灵”单击按钮保持活动状态,所以我添加了 $('.ui-btn').removeClass('ui-btn-积极的');在 preventDefault();
    • 唯一的不便是您必须在代码中的每个单击事件中设置 last_click_time。
    • 这不是一个很棒的 hack。好吧,它可能对你有用,但它仍然是一个令人讨厌的黑客,而且不是很可靠,因为我注意到事件触发之间的时间差异很大。我想知道Kaan的解决方案是否根本不起作用..我会尝试一下
    • 不要使用这个技巧!这会导致 Android 6+ 和几乎所有新的网络浏览器出现问题。我的按钮变得不可点击。真的很难发现这段代码是麻烦制造者!
    【解决方案2】:

    我处理我的类似情况非常接近 Soulwax 的解决方案,但是我不想通过跟踪时间间隔来阻碍用户的快速点击。相反,我只是在链接的数据对象中跟踪事件类型,如果它试图在 touchstart 之后立即处理点击,我会忽略该调用。

    $('.link').on('touchstart click', function(e){
      e.preventDefault();
    
      //Prevent against handling a click immediately after touchstart.
      if(e.type == "click" && $(this).data("lastTouch") == "touchstart"){
        e.stopImmediatePropagation();
        return false;
      }
      $(this).data("lastTouch", e.type);
    
      $('.nav-bar').toggleClass('active');
    });
    

    【讨论】:

      【解决方案3】:

      我认为这些双击/多次单击的原因是硬件加速故障,我正在经历同时单击+传播,传播很容易防止,但是由于在我的情况下不尊重 addEventListener 的第三个参数,我可以'即使使用先前回答的代码也不能防止双击,这就是我最终使用的

      function cw(event) // click wall
      { try {
          click_time_cw = (new Date()).getTime();
          if (click_time_cw && (click_time_cw - last_click_time_cw) < 350) {
              event.stopImmediatePropagation();
              event.preventDefault();
              add_log('prevented misclick [CW] '+(click_time_cw - last_click_time_cw));
              return true;
          }
          last_click_time_cw = click_time_cw;
          event.stopImmediatePropagation();
          event.stopPropagation();
          return false;
      } catch(e){ add_alert(e,"stpr"); } }
      

      您还必须在某处初始化 last_click_time_cw=(new Date()).getTime()

      这是一个点击示例:

      <button class="btn" onclick="if(cw(event)) return true; onclick_logic()">something</button>
      

      这似乎需要大量的工作和令人不快/丑陋的修复,但点击问题已经困扰我好几个月了,这似乎是我从一开始就应该做的事情

      【讨论】:

        【解决方案4】:

        我的修复有点不同。我使用touchend 而不是click 事件监听器,因为click 不会在每次需要时触发。假设您单击一个按钮,单击事件侦听器被触发,但如果您再次单击该按钮,则不会。

        它发生在任何类型的 DOM 元素上。我的环境是:

        • jQuery 1.9.1;
        • jQM 1.3.2;
        • Phonegap 3.5.0-0.21.14.

        这是我的代码:

        if (window.cordova) {
            // hack to avoid double tap
            var lastTapTime = new Date().getTime();
            function tryToAvoidDoubleTap(e){
                var tapTime = e["timeStamp"];
                if (tapTime && (tapTime - lastTapTime) < 300) {
                    // prevent double tap to happen
                    e.stopImmediatePropagation();
                    e.preventDefault();
                    // jQM button handling
                    if ($('.ui-btn').length)
                        $('.ui-btn').removeClass('ui-btn-active');
                    return false;
                }
                lastTapTime = tapTime;
            }
        
            // Wait for PhoneGap to load
            document.addEventListener("deviceready", onDeviceReady, false);
        
            // PhoneGap is ready
            function onDeviceReady() {
                document.addEventListener("touchend", tryToAvoidDoubleTap, true);
            }
        }
        

        【讨论】:

          【解决方案5】:

          我遇到了完全相同的问题,但我的应用/游戏需要用户能够在 touchstart 上双击。因此,上面提到的 scirra 解决方案无法使用,因为所需的 500 或 1000 毫秒延迟会杀死双击。

          经过一番挖掘,我注意到第一个(用户)点击和第二个(错误)点击之间的区别:

          event.originalEvent.touches 
          

          在第二个错误点击中不可用。 所以我写了这个错误检测助手来解决我的问题:

          function isDoubleTapBug (e) {
            // only handle touch events (in case your listener works on mouse events too)
            if (!'ontouchstart' in document.documentElement)) 
              return false;
            if (!e.originalEvent.touches) {
              e.preventDefault();
              e.stopPropagation();
              return true; // indicate to caller that it's a bug
            }
            return false;
          }
          

          然后在你的监听器中,这样做:

          document.addEventListener('touchstart', function (e) {
            if (isDoubleTapBug(e))
              return false;
            // now do your actual event handling stuff...      
          }
          

          【讨论】:

          • 你的代码有错别字,如果我没有错的话,if (!'ontouchstart' in document.documentElement)) 应该是 if (!'ontouchstart' in document.documentElement)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-19
          • 1970-01-01
          • 2017-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多