Lee*_*eem 151 javascript dom-events
我使用的jQuery.click处理上拉斐尔图形的鼠标点击事件,同时,我需要处理鼠标drag事件,鼠标拖动由mousedown,mouseup并mousemove在拉斐尔.
很难区分click,drag因为click还包含mousedown&mouseup,如何在Javascript中区分鼠标"点击"和鼠标"拖动"?
won*_*ng2 184
我认为不同之处在于存在mousemove介于拖动之间mousedown和mouseup拖动之间,而不是单击.
你可以这样做:
const element = document.createElement('div')
element.innerHTML = 'test'
document.body.appendChild(element)
let moved
let downListener = () => {
moved = false
}
element.addEventListener('mousedown', downListener)
let moveListener = () => {
moved = true
}
element.addEventListener('mousemove', moveListener)
let upListener = () => {
if (moved) {
console.log('moved')
} else {
console.log('not moved')
}
}
element.addEventListener('mouseup', upListener)
// release memory
element.removeEventListener('mousedown', downListener)
element.removeEventListener('mousemove', moveListener)
element.removeEventListener('mouseup', upListener)
Run Code Online (Sandbox Code Playgroud)
Gus*_*ues 34
如果您已经在使用jQuery:
var $body = $('body');
$body.on('mousedown', function (evt) {
$body.on('mouseup mousemove', function handler(evt) {
if (evt.type === 'mouseup') {
// click
} else {
// drag
}
$body.off('mouseup mousemove', handler);
});
});
Run Code Online (Sandbox Code Playgroud)
and*_*yrd 30
所有这些解决方案要么因微小的鼠标移动而中断,要么过于复杂。
这是一个使用两个事件侦听器的简单适应性解决方案。Delta 是以像素为单位的距离,您必须在向上和向下事件之间水平或垂直移动代码才能将其归类为拖动而不是点击。这是因为有时您会在抬起鼠标或手指之前将其移动几个像素。
const delta = 6;
let startX;
let startY;
element.addEventListener('mousedown', function (event) {
startX = event.pageX;
startY = event.pageY;
});
element.addEventListener('mouseup', function (event) {
const diffX = Math.abs(event.pageX - startX);
const diffY = Math.abs(event.pageY - startY);
if (diffX < delta && diffY < delta) {
// Click!
}
});
Run Code Online (Sandbox Code Playgroud)
nir*_*msu 18
这应该很好.与接受的答案类似(尽管使用jQuery),但isDragging只有当新鼠标位置与mousedown事件上的位置不同时才会重置标志.与已接受的答案不同,该答案适用于最新版本的Chrome,mousemove无论鼠标是否被移动,都会触发.
var isDragging = false;
var startingPos = [];
$(".selector")
.mousedown(function (evt) {
isDragging = false;
startingPos = [evt.pageX, evt.pageY];
})
.mousemove(function (evt) {
if (!(evt.pageX === startingPos[0] && evt.pageY === startingPos[1])) {
isDragging = true;
}
})
.mouseup(function () {
if (isDragging) {
console.log("Drag");
} else {
console.log("Click");
}
isDragging = false;
startingPos = [];
});
Run Code Online (Sandbox Code Playgroud)
mousemove如果要添加一点公差,也可以调整坐标检查(即将微小的运动视为咔嗒声,而不是拖拽).
Prz*_*mek 17
let drag = false;
document.addEventListener('mousedown', () => drag = false);
document.addEventListener('mousemove', () => drag = true);
document.addEventListener('mouseup', () => console.log(drag ? 'drag' : 'click'));Run Code Online (Sandbox Code Playgroud)
没有经历任何错误,正如其他人评论.
Fra*_*ino 12
正如mrjrdnthms在他对已接受答案的评论中指出的那样,这不再适用于Chrome(它总是触发鼠标移动),我已经改编了Gustavo的答案(因为我使用的是jQuery)来解决Chrome的行为问题.
var currentPos = [];
$(document).on('mousedown', function (evt) {
currentPos = [evt.pageX, evt.pageY]
$(document).on('mousemove', function handler(evt) {
currentPos=[evt.pageX, evt.pageY];
$(document).off('mousemove', handler);
});
$(document).on('mouseup', function handler(evt) {
if([evt.pageX, evt.pageY].equals(currentPos))
console.log("Click")
else
console.log("Drag")
$(document).off('mouseup', handler);
});
});
Run Code Online (Sandbox Code Playgroud)
该Array.prototype.equals功能来自这个答案
Dor*_*rus 11
var element = document;
Rx.Observable
.merge(
Rx.Observable.fromEvent(element, 'mousedown').mapTo(0),
Rx.Observable.fromEvent(element, 'mousemove').mapTo(1)
)
.sample(Rx.Observable.fromEvent(element, 'mouseup'))
.subscribe(flag => {
console.clear();
console.log(flag ? "drag" : "click");
});Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/@reactivex/rxjs@5.4.1/dist/global/Rx.js"></script>Run Code Online (Sandbox Code Playgroud)
这是@ wong2在答案中所做的直接克隆,但转换为RxJs.
也有趣的用途sample.所述sample操作者将采取的最新值从源(merge的mousedown和mousemove),并发射它时,可观察到的内(mouseup)发射.
使用具有5个像素x / y阈值的jQuery检测拖动:
var dragging = false;
$("body").on("mousedown", function(e) {
var x = e.screenX;
var y = e.screenY;
dragging = false;
$("body").on("mousemove", function(e) {
if (Math.abs(x - e.screenX) > 5 || Math.abs(y - e.screenY) > 5) {
dragging = true;
}
});
});
$("body").on("mouseup", function(e) {
$("body").off("mousemove");
console.log(dragging ? "drag" : "click");
});
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
var div = document.getElementById("div");
div.addEventListener("mousedown", function() {
window.addEventListener("mousemove", drag);
window.addEventListener("mouseup", lift);
var didDrag = false;
function drag() {
//when the person drags their mouse while holding the mouse button down
didDrag = true;
div.innerHTML = "drag"
}
function lift() {
//when the person lifts mouse
if (!didDrag) {
//if the person didn't drag
div.innerHTML = "click";
} else div.innerHTML = "drag";
//delete event listeners so that it doesn't keep saying drag
window.removeEventListener("mousemove", drag)
window.removeEventListener("mouseup", this)
}
})Run Code Online (Sandbox Code Playgroud)
body {
outline: none;
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
overflow: hidden;
}
#div {
/* calculating -5px for each side of border in case border-box doesn't work */
width: calc(100vw - 10px);
height: calc(100vh - 10px);
border: 5px solid orange;
background-color: yellow;
font-weight: 700;
display: grid;
place-items: center;
user-select: none;
cursor: pointer;
padding: 0;
margin: 0;
}Run Code Online (Sandbox Code Playgroud)
<html>
<body>
<div id="div">Click me or drag me.</div>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
最近在树列表中遇到了同样的问题,用户可以单击该项目或拖动它,创建了这个小类Pointer并将其放入我的utils.js
function Pointer(threshold = 10) {
let x = 0;
let y = 0;
return {
start(e) {
x = e.clientX;
y = e.clientY;
},
isClick(e) {
const deltaX = Math.abs(e.clientX - x);
const deltaY = Math.abs(e.clientY - y);
return deltaX < threshold && deltaY < threshold;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里你可以看到它的工作情况:
function Pointer(threshold = 10) {
let x = 0;
let y = 0;
return {
start(e) {
x = e.clientX;
y = e.clientY;
},
isClick(e) {
const deltaX = Math.abs(e.clientX - x);
const deltaY = Math.abs(e.clientY - y);
return deltaX < threshold && deltaY < threshold;
}
}
}
const pointer = new Pointer();
window.addEventListener('mousedown', (e) => pointer.start(e))
//window.addEventListener('mousemove', (e) => pointer.last(e))
window.addEventListener('mouseup', (e) => {
const operation = pointer.isClick(e)
? "Click"
: "Drag"
console.log(operation)
})Run Code Online (Sandbox Code Playgroud)