내가 사용하는 jQuery.click
한편, 내가 마우스 처리 할 필요가 라파엘 그래프에서 마우스 클릭 이벤트를 처리하는 drag
이벤트를 마우스 드래그로 구성 mousedown
, mouseup
및mousemove
라파엘있다.
구별하기 어려운 click
하고 drag
있기 때문에 click
도 포함 mousedown
& mouseup
, 어떻게 자바 스크립트에서 다음 “드래그”& 마우스 “클릭”마우스를 구별 할 수 있습니까?
답변
차이점은 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)
답변
이미 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);
});
});
답변
클리너 ES2015
let drag = false;
document.addEventListener('mousedown', () => drag = false);
document.addEventListener('mousemove', () => drag = true);
document.addEventListener('mouseup', () => console.log(drag ? 'drag' : 'click'));
다른 사람들이 언급했듯이 버그가 발생하지 않았습니다.
답변
이것은 잘 작동합니다. 허용 된 답변과 유사하지만 (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 = [];
});
mousemove
약간의 공차를 추가 하려면 좌표 체크인을 조정할 수도 있습니다 (예 : 작은 움직임은 드래그가 아닌 클릭으로 처리).
답변
Rxjs를 사용하고 싶다면 :
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");
});
<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>
이것은 @ wong2가 그의 대답에서 한 일을 직접 복제했지만 RxJ로 변환되었습니다.
의 흥미로운 사용 sample
. sample
오퍼레이터는 소스로부터의 최신의 값을 (뜻 merge
의 mousedown
및 mousemove
) 때 내부 관찰 (그것을 방출 mouseup
) 방출한다.
답변
mrjrdnthms가 허용 된 답변에 대한 그의 의견에서 지적한 것처럼, 이것은 더 이상 Chrome에서 작동하지 않으며 (항상 마우스 이동을 발생시킵니다) Chrome 동작을 해결하기 위해 Gustavo의 답변을 조정했습니다 (jQuery를 사용하기 때문에).
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);
});
});
Array.prototype.equals
기능이에서 오는 대답
답변
이러한 모든 솔루션은 작은 마우스 움직임으로 인해 깨지거나 지나치게 복잡합니다.
다음은 두 개의 이벤트 리스너를 사용하는 간단한 적응 형 솔루션입니다. 델타는 코드가 클릭이 아닌 드래그로 코드를 분류하기 위해 위쪽 및 아래쪽 이벤트 사이에서 가로 또는 세로로 이동해야하는 거리 (픽셀 단위)입니다. 마우스 나 손가락을 들어 올리기 전에 몇 픽셀 움직일 때가 있기 때문입니다.
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!
}
});