jQuery에서 "드래깅"을 감지 할 수 있습니까?


109

사용자가 링크를 클릭 할 때 나타나는 두근 거림이 있습니다.

문제는 동일한 링크를 클릭하고 드래그하여 재정렬 할 수 있다는 것입니다. 이 경우에는 두근 두근이 필요하지 않습니다. 실제로 어딘가에 가기를 기다리는 경우에만 나타납니다.

jQuery를 사용하여 클릭 및 드래그가 아닌 링크를 클릭하는 경우 에만 throbber가 표시되도록 허용 하는 이벤트 리스너를 만들 있습니까?


아마도 OOT? 내가 jQuery를 jQuery를 UI를 incluing, 내 자신의 mousedown, mouseup에,에서 mousemove 이벤트와 코드와 최고의 일입니다 한 하나 드래그 앤 드롭에 대한 몇 가지 접근 시도했습니다 github.com/haberman/jdragdrop을 .
Rafael Vega

무거운 프레임 워크가없는 또 다른 간단한 솔루션이 있습니다. blog.blakesimpson.co.uk/read/...
화학 프로그래머

답변:


225

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/



2
클릭이 "a"요소에 대한 드래그로 해석되지 않도록 드래그 임계 값을 추가 할 수 있습니다. x 및 y mousemove 이벤트에서 일정량의 변화를 찾으십시오.
Ash Blue

멋지다, 바람이 풀린 직후 mousemove 드래그 시작이 감지되는 즉시 코드를 입력했습니다. 감사합니다!
Valamas 2014

3
일부 경우 및 / 또는 브라우저에서 mousemove움직임이 없어도 한 번 이상 실행된다는 것을 알았으므로 이동시 변수를 증가시키고 mouseup jsfiddle.net/W7tvD/1649 에서 특정 임계 값을 확인하도록 변경했습니다. 이제 나에게 매력처럼 작동합니다. 감사합니다!
하프 비트

27

어떤 이유로 위의 솔루션이 저에게 효과가 없었습니다. 나는 다음과 같이 갔다.

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

거리 제한을 원하는대로 조정하거나 0으로 만들 수도 있습니다.


최고의 대답은 저를 많이 도왔습니다. 그냥 생각 : Math.sqrt는 실제로 필요하지 않으며 제곱 거리에서 더 잘 작동합니다 (sqrt는 느리고 UX에 영향을 줄 수 있음).
Bruno Ferreira

1
sqrt느리지 않고 UX에 영향을 미치지 않을 것입니다.
NateS

그래, 당신의 물리 엔진, 아닌 JQuery와 클릭 핸들러 ...의 내부 루프에서 불필요한 제곱근에 대한 걱정
PeterT

19

jQuery UI를 사용하면됩니다!

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

  },
  drag: function() {

  },
  stop: function() {

  }
});

6
jquery-ui가 필요하지만 가장 쉬운 방법입니다.
Ortomala Lokni

5
$(".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 이벤트 바인딩 해제 (bind 및 unbind는 더 이상 사용되지 않음)를 바인딩합니다. 두 개의 mousemove 이벤트 사이에서 마우스 x 및 y 위치의 변화를 감지 할 수도 있습니다.


3

이것을 시도하십시오 : '드래그'상태가 언제인지 보여줍니다. ;) 바이올린 링크

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

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

2

클릭이 아래로 끌려 가고 끌 때만 실행되도록 허용 된 답변에서 분기했습니다 .

마우스를 누르고 있지 않을 때 내 기능이 실행 중이었습니다. 이 기능도 원하는 경우 업데이트 된 코드는 다음과 같습니다.

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

    }
);

1

이 가장 간단한 방법은 터치 시작, 터치 이동 및 터치 종료입니다. 그것은 PC와 터치 장치 모두에서 작동하며 jquery 문서에서 확인하고 이것이 최상의 솔루션이되기를 바랍니다. 행운을 빕니다


1

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

^^


1

mouseup 이벤트를 수신 할 때 부작용이 없도록 요소의 draggable 속성을 false로 설정해야 합니다.

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

0

타이머를 설정해야합니다. 타이머 시간이 초과되면 스 로버를 시작하고 클릭을 등록합니다. 드래그가 발생하면 타이머를 지우면 완료되지 않습니다.


1
.. 매우 영리합니다. 항력을 어떻게 감지합니까?
여행

1
Draggable을 설정할 때 onDrag 이벤트가 있어야합니다. 거기에 연결하십시오.
Diodeus-James MacFarlane

0

jQueryUI를 사용하는 경우-onDrag 이벤트가 있습니다. 그렇지 않은 경우 리스너를 click ()이 아닌 mouseup ()에 연결하십시오.


1
mouseup은 드래그와 클릭을 어떻게 구별합니까?
여행

흠-그래 충분히 생각하지 못한 것 같아요. 아마도 당신은 마우스의 좌표를 기록하는 하나의 리스너를 mousedown에 연결할 수 있습니다. 그런 다음 mouseup에서 마우스의 좌표가 동일하거나 실제로 가까우면 클릭 연결로 간주합니다.
Quasipickle 2010

이것은 작동하지 않습니다 : stackoverflow.com/questions/12231147/…
Chuck Le Butt

대답은 또한 4 살입니다.
Quasipickle 2014 년

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

0

변수를 설정할 필요가 없으며 데이터 속성에서 이동하는 경우에만 설정할 수 있습니다.

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

0

항상 마우스 위치를 추적하고 왼쪽, 오른쪽, 위쪽, 아래쪽 끌기를 감지하는 기능이 필요했습니다. 또한 클릭시 트리거되지 않지만 최소 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;
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.