【问题标题】:Can you detect "dragging" in jQuery?你能在 jQuery 中检测到“拖动”吗?
【发布时间】:2011-05-06 20:11:50
【问题描述】:

我有一个 throbber,当用户点击链接时会出现。

问题是可以单击并拖动相同的链接以重新排列。在这种情况下,我不需要颤抖者出现。只有当它真的在等待去某个地方时它才需要出现。

如何使用 jQuery 创建一个事件侦听器,该侦听器仅在点击链接时才允许出现 throbber,而不是点击和拖动?

【问题讨论】:

  • 也许是 OOT?我尝试了几种使用 jQuery 进行拖放的方法,包括 jQuery UI,我自己的带有 mousedown、mouseup、mousemove 事件的代码,效果最好的一种是 github.com/haberman/jdragdrop
  • 这是另一个没有任何繁重框架的简单解决方案。 blog.blakesimpson.co.uk/read/…

标签: jquery


【解决方案1】:

您需要设置一个计时器。当计时器超时时,启动颤动器并注册点击。发生拖动时,清除计时器,使其永远不会完成。

【讨论】:

  • ..非常聪明,你如何检测到拖拽?
  • 设置 Draggable 时,应该有一个 onDrag 事件。把它挂在那里。
【解决方案2】:

如果您使用的是 jQueryUI - 有一个 onDrag 事件。如果不是,则将侦听器附加到 mouseup(),而不是 click()。

【讨论】:

  • mouseup 如何区分拖动和点击?
  • 嗯 - 是的,我想我想得还不够。也许您可以将一个监听器附加到 mousedown 以记录鼠标的坐标。然后,如果鼠标在 mouseup 上的坐标相同(或非常接近),则认为它是一次点击。
  • 答案也是 4 岁 - 考虑一下。
【解决方案3】:

在 mousedown 时,开始设置状态,如果触发 mousemove 事件,记录它,最后在 mouseup 时,检查鼠标是否移动。如果它移动了,我们一直在拖。如果我们没有移动,那就是点击。

var isDragging = false;
$("a")
.mousedown(function() {
    isDragging = false;
})
.mousemove(function() {
    isDragging = true;
 })
.mouseup(function() {
    var wasDragging = isDragging;
    isDragging = false;
    if (!wasDragging) {
        $("#throbble").toggle();
    }
});

这是一个演示:http://jsfiddle.net/W7tvD/1399/

【讨论】:

  • 嘿..你能帮我解决这个stackoverflow.com/questions/19703617/…
  • 您可能想要添加一个拖动阈值,这样您的点击就不会被解释为对“a”元素的拖动。只需在 x 和 y mousemove 事件中寻找一定量的变化。
  • 太棒了,在风解开mousemove之后,一旦检测到拖动开始,我就让我的代码立即行动。谢谢你!
  • 我发现在某些情况和/或浏览器中,即使没有任何移动,mousemove 仍会至少被触发一次,因此我将其更改为在移动时增加变量,然后检查mouseup jsfiddle.net/W7tvD/1649 的某个阈值现在对我来说就像一个魅力,谢谢!
【解决方案4】:

由于某种原因,上述解决方案对我不起作用。我选择了以下内容:

$('#container').on('mousedown', function(e) {
    $(this).data('p0', { x: e.pageX, y: e.pageY });
}).on('mouseup', function(e) {
    var p0 = $(this).data('p0'),
        p1 = { x: e.pageX, y: e.pageY },
        d = Math.sqrt(Math.pow(p1.x - p0.x, 2) + Math.pow(p1.y - p0.y, 2));

    if (d < 4) {
        alert('clicked');
    }
})

您可以随意调整距离限制,甚至可以将其调整为零。

【讨论】:

  • 最佳答案,对我帮助很大。只是一个想法:Math.sqrt 并不是真正必要的,更好地处理平方距离(sqrt 很慢,可能会影响用户体验)。
  • sqrt 并不慢,不会影响用户体验,即使你做了数百次也不会。
  • 是的,担心你的物理引擎内部循环中不必要的平方根,而不是你的 jquery 点击处理程序......
【解决方案5】:

对于这种最简单的方法是触摸开始、触摸移动和触摸结束。这适用于 PC 和触摸设备,只需在 jquery 文档中检查它,并希望这是最适合您的解决方案。祝你好运

【讨论】:

    【解决方案6】:

    试试这个:它显示什么时候是“拖动”状态。 ;) fiddle link

    $(function() {
        var isDragging = false;
        $("#status").html("status:");
        $("a")
        .mousedown(function() {
            $("#status").html("status: DRAGGED");        
        })
        .mouseup(function() {
            $("#status").html("status: dropped");   
        });
    
        $("ul").sortable();
    });
    

    【讨论】:

      【解决方案7】:

      基于 Simen Echholt 答案的 jQuery 插件。我称之为单击。

      /**
       * jQuery plugin: Configure mouse click that is triggered only when no mouse move was detected in the action.
       * 
       * @param callback
       */
      jQuery.fn.singleclick = function(callback) {
          return $(this).each(function() {
              var singleClickIsDragging = false;
              var element = $(this);
      
              // Configure mouse down listener.
              element.mousedown(function() {
                  $(window).mousemove(function() {
                      singleClickIsDragging = true;
                      $(window).unbind('mousemove');
                  });
              });
      
              // Configure mouse up listener.
              element.mouseup(function(event) {
                  var wasDragging = singleClickIsDragging;
                  singleClickIsDragging = false;
                  $(window).unbind('mousemove');
                  if(wasDragging) {
                      return;
                  }
      
                  // Since no mouse move was detected then call callback function.
                  callback.call(element, event);
              });
          });
      };
      

      使用中:

      element.singleclick(function(event) {
          alert('Single/simple click!');
      });
      

      ^^

      【讨论】:

        【解决方案8】:
        // here is how you can detect dragging in all four directions
        var isDragging = false;
        $("some DOM element").mousedown(function(e) {
            var previous_x_position = e.pageX;
            var previous_y_position = e.pageY;
        
            $(window).mousemove(function(event) {
                isDragging = true;
                var x_position = event.pageX;
                var y_position = event.pageY;
        
                if (previous_x_position < x_position) {
                    alert('moving right');
                } else {
                    alert('moving left');
                }
                if (previous_y_position < y_position) {
                    alert('moving down');
                } else {
                    alert('moving up');
                }
                $(window).unbind("mousemove");
            });
        }).mouseup(function() {
            var wasDragging = isDragging;
            isDragging = false;
            $(window).unbind("mousemove");
        });
        

        【讨论】:

          【解决方案9】:
          $(".draggable")
          .mousedown(function(e){
              $(this).on("mousemove",function(e){
                  var p1 = { x: e.pageX, y: e.pageY };
                  var p0 = $(this).data("p0") || p1;
                  console.log("dragging from x:" + p0.x + " y:" + p0.y + "to x:" + p1.x + " y:" + p1.y);
                  $(this).data("p0", p1);
              });
          })
          .mouseup(function(){
              $(this).off("mousemove");
          });
          

          此解决方案使用“on”和“off”函数来绑定 unbind a mousemove 事件(不推荐使用 bind 和 unbind)。您还可以检测两个 mousemove 事件之间鼠标 x 和 y 位置的变化。

          【讨论】:

          • 这个解决方案的问题现在在每个mousedown 上都会有另一个事件处理程序添加到this 上,导致该函数的主体越来越多地执行数次。
          【解决方案10】:

          使用 jQuery UI 就可以做到这一点!

          $( "#draggable" ).draggable({
            start: function() {
          
            },
            drag: function() {
          
            },
            stop: function() {
          
            }
          });
          

          【讨论】:

          • 你需要jquery-ui,但这是最简单的方法。
          【解决方案11】:

          你不必设置变量,你可以设置它是否在数据属性中移动

          $youtubeSlider.find('a')
              .on('mousedown', function (e) {
                  $(this).data('moving', false);
              })
              .on('mousemove', function (e) {
                  $(this).data('moving', true);
              })
              .on('mouseup', function (e) {
                  if (!$(this).data('moving')) {
                      // Open link
                  }
              });
          

          【讨论】:

            【解决方案12】:

            确保将元素的 draggable 属性设置为 false,这样在监听 mouseup 事件时就不会产生副作用:

            <div class="thing" draggable="false">text</div>
            

            然后,你就可以使用jQuery了:

            $(function() {
              var pressed, pressX, pressY,
                  dragged,
                  offset = 3; // helps detect when the user really meant to drag
            
              $(document)
              .on('mousedown', '.thing', function(e) {
                pressX = e.pageX;
                pressY = e.pageY;
                pressed = true;
              })
              .on('mousemove', '.thing', function(e) {
                if (!pressed) return;
                dragged = Math.abs(e.pageX - pressX) > offset ||
                          Math.abs(e.pageY - pressY) > offset;
              })
              .on('mouseup', function() {
                dragged && console.log('Thing dragged');
                pressed = dragged = false;
              });
            });
            

            【讨论】:

              【解决方案13】:

              我从接受的答案分支到仅在单击被按住并拖动时运行

              当我没有按住鼠标时,我的函数正在运行。如果您还需要此功能,请查看更新后的代码:

              var isDragging = false;
              var mouseDown = false;
              
              $('.test_area')
                  .mousedown(function() {
                      isDragging = false;
                      mouseDown = true;
                  })
                  .mousemove(function(e) {
                      isDragging = true;
              
                      if (isDragging === true && mouseDown === true) {
                          my_special_function(e);
                      }
                   })
                  .mouseup(function(e) {
              
                      var wasDragging = isDragging;
              
                      isDragging = false;
                      mouseDown = false;
              
                      if ( ! wasDragging ) {
                          my_special_function(e);
                      }
              
                  }
              );
              

              【讨论】:

                【解决方案14】:

                我需要一个始终跟踪鼠标位置并检测左、右、上、下拖动的功能。它也不会在点击时触发,但需要至少 15px 的移动

                /**
                 * Check for drag when moved minimum 15px
                 * Same time keep track of mouse position while dragging
                 */
                // Variables to be accessed outside in other functions
                var dragMouseX;
                var dragMouseY;
                var myDragging = false; // true or false
                var dragDirectionX = false; // left or right
                var dragDirectionY = false; // top or bottom
                
                $(document).on("mousedown", function(e) {
                    // Reset some variables on mousedown
                    var lastDirectionCheck = e.timeStamp;
                    var dragStartX = e.pageX;
                    var dragStartY = e.pageY;
                    dragMouseX = e.pageX;
                    dragMouseY = e.pageY;
                    myDragging = false;
                    dragDirectionX = false;
                    dragDirectionY = false;
                
                    // On the move
                    $(document).on("mousemove", function(e) {
                        dragMouseX = e.pageX;
                        dragMouseY = e.pageY;
                
                        // Recalculate drag direction every 200ms in case user changes his mind
                        if (e.timeStamp > (lastDirectionCheck + 200)) {
                            dragStartX = dragMouseX;
                            dragStartY = dragMouseY;
                            lastDirectionCheck = e.timeStamp;
                        }
                
                        // Check for drag when moved minimum 15px in any direction
                        if (!myDragging && Math.abs(dragStartX - dragMouseX) > 15 || Math.abs(dragStartY - dragMouseY) > 15) {
                            myDragging = true;
                        }
                        if (myDragging) {
                            // Check drag direction X
                            if (dragStartX > dragMouseX) dragDirectionX = 'left';
                            if (dragStartX < dragMouseX) dragDirectionX = 'right';
                
                            // Check drag direction Y
                            if (dragStartY > dragMouseY) dragDirectionY = 'top';
                            if (dragStartY < dragMouseY) dragDirectionY = 'bottom';
                
                            // console.log(dragDirectionX + ' ' + dragDirectionY);
                        }
                    });
                });
                
                // Reset some variables again on mouseup
                $(document).on("mouseup", function() {
                    $(document).off("mousemove");
                    myDragging = false;
                    dragDirectionX = false;
                    dragDirectionY = false;
                });
                

                【讨论】:

                  猜你喜欢
                  • 2012-05-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-09-21
                  • 2018-01-26
                  • 2011-02-05
                  • 1970-01-01
                  • 2013-01-15
                  • 2011-08-29
                  相关资源
                  最近更新 更多