마우스 "클릭"과 "끌기"를 구별하는 방법
내가 사용하는 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);
});
});
이것은 잘 작동합니다. 허용 된 답변과 유사하지만 (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
약간의 공차를 추가 하려면 좌표 체크인을 조정할 수도 있습니다 (예 : 작은 움직임은 드래그가 아닌 클릭으로 처리).
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
기능이에서 오는 대답
클리너 ES2015
let drag = false;
document.addEventListener('mousedown', () => drag = false);
document.addEventListener('mousemove', () => drag = true);
document.addEventListener('mouseup', () => console.log(drag ? 'drag' : 'click'));
다른 사람들이 언급했듯이 버그가 발생하지 않았습니다.
If you feel like using 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>
This is a direct clone of what @wong2 did in his answer, but converted to RxJs.
Also interesting use of sample
. The sample
operator will take the latest value from the source (the merge
of mousedown
and mousemove
) and emit it when the inner observable (mouseup
) emits.
Using jQuery with a 5 pixel x/y theshold to detect the drag:
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");
});
If just to filter out the drag case, do it like this:
var moved = false;
$(selector)
.mousedown(function() {moved = false;})
.mousemove(function() {moved = true;})
.mouseup(function(event) {
if (!moved) {
// clicked without moving mouse
}
});
Pure JS with DeltaX and DeltaY
This DeltaX and DeltaY as suggested by a comment in the accepted answer to avoid the frustrating experience when trying to click and get a drag operation instead due to a one tick mousemove.
deltaX = deltaY = 2;//px
var element = document.getElementById('divID');
element.addEventListener("mousedown", function(e){
if (typeof InitPageX == 'undefined' && typeof InitPageY == 'undefined') {
InitPageX = e.pageX;
InitPageY = e.pageY;
}
}, false);
element.addEventListener("mousemove", function(e){
if (typeof InitPageX !== 'undefined' && typeof InitPageY !== 'undefined') {
diffX = e.pageX - InitPageX;
diffY = e.pageY - InitPageY;
if ( (diffX > deltaX) || (diffX < -deltaX)
||
(diffY > deltaY) || (diffY < -deltaY)
) {
console.log("dragging");//dragging event or function goes here.
}
else {
console.log("click");//click event or moving back in delta goes here.
}
}
}, false);
element.addEventListener("mouseup", function(){
delete InitPageX;
delete InitPageY;
}, false);
element.addEventListener("click", function(){
console.log("click");
}, false);
For a public action on an OSM map (position a marker on click) the question was: 1) how to determine the duration of mouse down->up (you can't imagine creating a new marker for each click) and 2) did the mouse move during down->up (i.e user is dragging the map).
const map = document.getElementById('map');
map.addEventListener("mousedown", position);
map.addEventListener("mouseup", calculate);
let posX, posY, endX, endY, t1, t2, action;
function position(e) {
posX = e.clientX;
posY = e.clientY;
t1 = Date.now();
}
function calculate(e) {
endX = e.clientX;
endY = e.clientY;
t2 = (Date.now()-t1)/1000;
action = 'inactive';
if( t2 > 0.5 && t2 < 1.5) { // Fixing duration of mouse down->up
if( Math.abs( posX-endX ) < 5 && Math.abs( posY-endY ) < 5 ) { // 5px error on mouse pos while clicking
action = 'active';
// --------> Do something
}
}
console.log('Down = '+posX + ', ' + posY+'\nUp = '+endX + ', ' + endY+ '\nAction = '+ action);
}
참고URL : https://stackoverflow.com/questions/6042202/how-to-distinguish-mouse-click-and-drag
'IT' 카테고리의 다른 글
Chrome 확장 프로그램 : 콘텐츠 스크립트에서 localStorage에 액세스 (0) | 2020.06.15 |
---|---|
ECMAScript 6에는 추상 클래스에 대한 규칙이 있습니까? (0) | 2020.06.15 |
정확히 Activity.finish () 메소드가 수행하는 작업은 무엇입니까? (0) | 2020.06.15 |
코 틀린에서의 관용적 로깅 방법 (0) | 2020.06.15 |
R의 회전 축 레이블 (0) | 2020.06.15 |