Can you detect "dragging" in jQuery?

I have a throbber that is to appear when a user clicks a link.

The problem is is that that same link can be clicked and dragged to be rearranged. In this case, I wouldn't need the throbber to appear. It only needs to appear if its actually waiting to go somewhere.

How can I, with jQuery, create an event listener that would only allow a throbber to appear if its a click through to a link, and not a click and drag?

199088 次浏览

你得设个计时器。当计时器超时时,启动脉冲器并注册点击。当拖动发生时,清除计时器,使它永远不会完成。

If you're using jQueryUI - there is an onDrag event. If you're not, then attach your listener to mouseup(), not click().

在 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/

For some reason, the above solutions were not working for me. I went with the following:

$('#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');
}
})

You can tweak the distance limit to whatever you please, or even take it all the way to zero.

这个最简单的方法是触摸开始,触摸移动和触摸结束。这对 PC 和触摸设备都有效,只需在 jquery 文档中检查它,并希望这是最好的解决方案。祝你好运

尝试这样做: 它显示“拖动”状态的时间。 ;) fiddle link

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


$("ul").sortable();
});

基于 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);
});
});
};

In use:

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

^^

// 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");
});
$(".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”函数绑定一个取消绑定的 mousemove 事件(不推荐绑定和取消绑定)。您还可以检测两个鼠标移动事件之间鼠标 x 和 y 位置的变化。

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

$( "#draggable" ).draggable({
start: function() {


},
drag: function() {


},
stop: function() {


}
});

您不必设置变量,只需设置它是否在数据属性中移动

$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
}
});

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

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

Then, you can use 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;
});
});

我从公认的 只有当单击被按下并拖动时才运行答案分支出来。

My function was running when I wasn't holding the mouse down. Here's the updated code if you also want this functionality:

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);
}


}
);

我需要一个功能,始终跟踪鼠标的位置,并检测左,右,顶部,底部拖动。它也不触发点击,但需要至少15像素的移动

/**
* 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;
});

派对迟到了,但是这个代码也能检测触摸事件(手机,平板电脑)。

$(".draggable").on('touchstart mousedown', function(ev) {
ev.preventDefault();
$(this).on("touchmove mousemove",function(e){
var x = e.pageX || e.changedTouches[0].pageX;
var y = e.pageY || e.changedTouches[0].pageY;
var p1 = { x: x, y: y };
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", p0);
});
}).on('touchend mouseup', function(ev) {
ev.preventDefault();
$(this).off("touchmove mousemove");
});