【问题标题】:jQuery on 'double click' event (dblclick for mobile)jQuery on '双击'事件(dblclick for mobile)
【发布时间】:2014-12-19 06:14:35
【问题描述】:

我有以下jquery事件处理函数:

$('.target').on('dblclick', function() {
    //respond to double click event
});

我的问题是此事件处理程序不适用于触摸设备(iPhone、iPad...)。谁能推荐一个可靠的替代 dblclick 的替代方案,它适用于触摸设备,并且仍然允许在全尺寸设备上舒适地双击使用?

【问题讨论】:

标签: javascript jquery touch


【解决方案1】:

我最终构建了一个可在移动设备和桌面设备上使用的自定义双击功能:

var touchtime = 0;
$(".target").on("click", function() {
    if (touchtime == 0) {
        // set first click
        touchtime = new Date().getTime();
    } else {
        // compare first click to this click and see if they occurred within double click threshold
        if (((new Date().getTime()) - touchtime) < 800) {
            // double click occurred
            alert("double clicked");
            touchtime = 0;
        } else {
            // not a double click so set as a new first click
            touchtime = new Date().getTime();
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="target">Double click me</div>

或者,这里是JSfiddle Demo

【讨论】:

  • @matteo,对我来说,它可以在移动设备上运行,但是在您单击一次后检测单击时会出现一些问题
  • 我发现“捏缩放”手势触发了双击 - 至少在 IOS 上。我使用 if ((now - touchtime) 150) 来解决它...
【解决方案2】:

将此添加到您的 index.html

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>

我发现移动缩放功能会摆脱 Jquery 的 dblclick。基本上它说你的视口不会有效地改变关闭缩放。这适用于我运行 Chrome 的 Nexus 5。

【讨论】:

【解决方案3】:

您可以在元素上绑定多个事件侦听器,并为触摸设备使用 jQuery 的 tap 事件。

$( ".target" ).on({
  dbclick: function() {
    //do stuff
  }, touch: function() {
    //do the same stuff
  }
});

【讨论】:

    【解决方案4】:

    感谢您的解决方案 - 我唯一做的就是添加一个超时,以便它们可以被视为单独的事件

    var touchtime = 0;
    var delay = 800;
    var action = null;
    $(".target").on("click", function() {
      /*Double Click */
      if((new Date().getTime() - touchtime) < delay){
         clearTimeout(action)
         alert('dbl');
         touchtime=0;
      }
      /* Single Click */
      else{
         touchtime = new Date().getTime();
         action = setTimeout(function(){
            alert('single');
         },delay);
      }
    }));
    

    虽然我还没有测试过,但可能还值得在任何 HTML &lt;meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/&gt; 的标题部分添加以下内容:To "user-scalable=no" or not to "user-scalable=no"

    【讨论】:

      【解决方案5】:

      我知道问题已得到解答,但认为值得提出我一直使用的解决方案,干杯:

      ​​>
          var doubleClicked = false;
          $('.target').on('click', function() {   
              if (doubleClicked) {
                  //do what you want to do on double click here
              }
              doubleClicked = true;
              setTimeout(() => {
                  doubleClicked = false;
              }, 300);
          });
      

      【讨论】:

        【解决方案6】:

        @JRulle 的标记答案似乎仅适用于单个对象,如果您有许多具有相同类的实例,它们将被视为单个对象 查看示例
        Fiddle example

        我的解决方案似乎在这种情况下有效

        var touchtime = 0;
        $('.target').on('click', function() {
          if (touchtime == 0) {
            touchtime = new Date().getTime();
          } else {
            if (((new Date().getTime()) - touchtime) < 800) {
              alert("double clicked");
              touchtime = 0;
            } else {
              touchtime = 0;
            }
          }
        });
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <p class="target">click me!</p>
        <p class="target">then click me!</p>
        
        <a href="#">click link</a>

        【讨论】:

          【解决方案7】:

          具有自己的双击计数器的多个目标。接受的解决方案有 2 个错误,已在此处修复:

          1. 如果单击目标并在外部单击并在 800 毫秒内再次单击目标,则会触发双击事件。

          2. 如果您有多个目标,请在 800 毫秒内单击不同的目标,然后会触发双击事件。

          $(document).on("click", function(e)
          {
              var MAX_DELAY_IN_MS = 800;
              var current_time = new Date();
              var targets = $(".target");
              
              if ((typeof last_target == "undefined") || 
                  (last_target == 0))
              {
                  last_target = e.target;
                  last_click  = current_time;
              }
              else
              {
                  if ((last_target == e.target) && 
                      ((targets.is(e.target) == true) || 
                       (targets.has(e.target).length !== 0)) &&
                      (current_time - last_click < MAX_DELAY_IN_MS))
                  {
                      alert("double clicked");
                  }
                  last_target = 0;
                  last_click  = 0;
              }
          });
          div{display:inline-block; width:30px; height:30px; margin:5px;}
          .target{background-color:lime;}
          .no_target{background-color:orange;}
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
          
          <div class="target"></div>
          <div class="target"></div>
          <div class="no_target"></div>
          <div class="target"></div>

          【讨论】:

          • 请详细说明您的答案与接受的答案有何不同以及您认为值得发布的原因是什么?
          • 谢谢非尼西尔!我是新来的。接受的解决方案有一个错误。如果你点击“点击我!”然后点击“然后点击我!”在 800 毫秒内,双击事件触发,但它不是真正的双击。在我的解决方案中,事件是分开处理的。
          • 我正在考虑我的解决方案,发现另一个错误。如果您在 800 毫秒内单击第一个目标、第二个目标、第一个目标,则双击事件会触发(不应该)。就我的目的而言,这就足够了。也许没有一个解决方案是完美的......
          • 请考虑将这些详细信息添加到您的答案中 - 这可以解释差异并可能帮助您更快地获得声誉
          • 好主意,谢谢 fenixil!顺便说一句,声誉不是我的目标。
          【解决方案8】:

          以编程方式,上面给出的所有答案都很好。 当你双击鼠标按钮时,它只是你手指上的质量, 所以它可以很快......

          另一方面,当点击触摸屏时,通常会涉及更大的物理质量。 更大的质量意味着更慢的时间。 所以我的做法是“点击两次”而不是双击。

          表示全局变量,例如var ClickCounter=0; 在函数范围内

           ClickCounter++;
           Check if  ClickCounter ==2.
           Execute your Code.
           Reset counter ClickCounter=0 
           else return false or execute another code
          

          【讨论】:

            【解决方案9】:

            我对上面的代码进行了改进,单击后没有检测到双击:

            var touchtime = 0;
            $(".target").on("click", function() {
              if (((new Date().getTime()) - touchtime) < 500) {
                alert("double clicked");
              }
              touchtime = new Date().getTime();
            });
            

            此代码检测所有双击。我还将触摸时间减少到 500 毫秒(标准双击时间)。

            【讨论】:

              【解决方案10】:

              唯一的方法是自己检测双击。您可以通过保持最后一个 touch 事件时间戳来做到这一点,如下所示:

              if (e.touches.length === 1) {
                if (this.lastTouchEventTimeStamp) {
                  const timeInMillisecondsSinceLastTouch = e.timeStamp - this.lastTouchEventTimeStamp;
                  if (timeInMillisecondsSinceLastTouch > 80 && timeInMillisecondsSinceLastTouch < 400) {
                    // double tap will be detected here
                    this.lastTouchEventTimeStamp = undefined;
              
                    const dblClickEvent = new DragEvent('dblclick', {
                      view: window,
                      bubbles: true,
                      cancelable: true
                    });
              
                    e.target.dispatchEvent(dblClickEvent);
                  }
                }
              
                this.lastTouchEventTimeStamp = e.timeStamp;
              }
              

              【讨论】:

                【解决方案11】:

                遇到了这个帖子,想提供一个更新的答案。

                function doubleClick(event, callback) {
                  var touchtime = $(event.target).data("touch-time");
                  if (touchtime == undefined || touchtime == 0) {
                    // set first click
                    $(event.target).data("touch-time", new Date().getTime());
                  } else {
                    // compare first click to this click and see if they occurred within double click threshold
                    if (((new Date().getTime()) - touchtime) < 800) {
                      // double click occurred
                      callback();
                      $(event.target).data("touch-time", 0);
                    } else {
                      // not a double click so set as a new first click
                      $(event.target).data("touch-time", new Date().getTime());
                    }
                  }
                }
                

                然后可以按如下方式使用:

                $(selector).click(function(event){
                  doubleClick(event, function(){
                    console.log("Hello World");
                  });
                });
                

                这使用数据属性而不是全局变量来获取/设置触摸时间。

                标准的dblclick 应该可以在现代移动浏览器中使用。

                【讨论】:

                  【解决方案12】:

                  就是这样……在 CoffeeScript 中

                  onDblClick = -> "...your function to be fired..."
                  dbl_click = null
                  $(element).on 'mousedown', ->
                     onDblClick() if dbl_click
                     dbl_click = true
                     setTimeout () ->
                         dbl_click = false            
                     , 250
                  

                  【讨论】:

                    【解决方案13】:

                    您需要在函数末尾输入“return false”,如下所示

                    var touchtime = 0;
                    $('.dbclickopen').click(function() {
                        if(touchtime == 0) {
                            //set first click
                            touchtime = new Date().getTime();
                        } else {
                            //compare first click to this click and see if they occurred within double click threshold
                            if(((new Date().getTime())-touchtime) < 800) {
                                //double click occurred
                                touchtime = 0;
                                window.location = this.href;
                            } else {
                                //not a double click so set as a new first click
                                touchtime = new Date().getTime();
                            }
                        }
                        return false;
                    });
                    

                    【讨论】:

                    • 即使返回 false,它也不能在移动设备上运行,至少不能在 Android 上运行。出于某种原因,不会阻止默认行为(缩放/取消缩放)
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多