[javascript] jQuery 드래그 앤 드롭으로 클릭 이벤트 방지

페이지에 jQuery로 드래그 할 수있는 요소가 있습니다. 이러한 요소에 다른 페이지 (예 : 일반 링크)로 이동하는 클릭 이벤트가 있습니까?

드래그 앤 드롭 상태가 아닌 클릭을 허용하면서 이러한 요소를 놓을 때 클릭이 발생하지 않도록하는 가장 좋은 방법은 무엇입니까?

나는 정렬 가능한 요소 에이 문제가 있지만 일반적인 드래그 앤 드롭에 대한 해결책을 갖는 것이 좋다고 생각합니다.

나는 스스로 문제를 해결했다. 그 후 Scriptaculous대해 동일한 솔루션 이 존재 한다는 것을 발견 했지만 누군가이를 달성하는 더 좋은 방법이있을 수 있습니다.



답변

나를 위해 잘 작동하고 시간 초과가 필요하지 않은 솔루션 : (예, 약간 현학적입니다 😉

드래그가 시작될 때 요소에 마커 클래스를 추가합니다 (예 : ‘noclick’). 요소가 드롭되면 클릭 이벤트가 트리거됩니다.보다 정확하게는 드래그가 끝나면 실제로 유효한 타겟에 드롭 할 필요가 없습니다. 클릭 핸들러에서 마커 클래스가 있으면 제거하고 그렇지 않으면 클릭이 정상적으로 처리됩니다.

$('your selector').draggable({
    start: function(event, ui) {
        $(this).addClass('noclick');
    }
});

$('your selector').click(function(event) {
    if ($(this).hasClass('noclick')) {
        $(this).removeClass('noclick');
    }
    else {
        // actual click event code
    }
});


답변

해결책은 드래그 시작시 클릭이 전파되는 것을 방지하는 클릭 핸들러를 추가하는 것입니다. 그리고 드롭이 수행 된 후 해당 핸들러를 제거하십시오. 클릭 방지가 작동하려면 마지막 작업이 약간 지연되어야합니다.

정렬 가능한 솔루션 :

...
.sortable({
...
        start: function(event, ui) {
            ui.item.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.item.unbind("click.prevent");}, 300);
        }
...
})

드래그 가능한 솔루션 :

...
.draggable({
...
        start: function(event, ui) {
            ui.helper.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
        }
...
})


답변

나는 같은 문제가 있었고 여러 접근법을 시도했지만 아무도 나를 위해 일하지 않았습니다.

해결 방법 1

$('.item').click(function(e)
{
    if ( $(this).is('.ui-draggable-dragging') ) return false;
});

나를 위해 아무것도하지 않습니다. 드래그가 완료된 후 항목이 클릭됩니다.

솔루션 2 (Tom de Boer 작성)

$('.item').draggable(
{
    stop: function(event, ui)
    {
         $( event.originalEvent.target).one('click', function(e){ e.stopImmediatePropagation(); } );
    }
});

이것은 잘 작동하지만 한 가지 경우에 실패합니다.

var body = $('body')[0];
req = body.requestFullScreen || body.webkitRequestFullScreen || body.mozRequestFullScreen;
req.call(body);

솔루션 3 (Sasha Yanovets 제작)

 $('.item').draggable({
        start: function(event, ui) {
            ui.helper.bind("click.prevent",
                function(event) { event.preventDefault(); });
        },
        stop: function(event, ui) {
            setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
        }
})

이것은 나를 위해 작동하지 않습니다.

솔루션 4- 잘 작동하는 유일한 솔루션

$('.item').draggable(
{
});
$('.item').click(function(e)
{
});

네, 그게 다입니다. 올바른 순서가 트릭을 수행합니다. 먼저 draggable ()을 바인딩 한 다음 click () 이벤트를 바인딩해야합니다. click () 이벤트에 전체 화면 토글 코드를 입력해도 드래그 할 때 전체 화면으로 이동하지 않았습니다. 나 한테 딱이야!


답변

클릭 이벤트가 드래그 가능하거나 정렬 가능한 이벤트 이후에 정의 된 경우에만 클릭 이벤트가 작동하지 않는 것 같다고 여기에 추가하고 싶습니다. 클릭이 먼저 추가되면 드래그시 활성화됩니다.


답변

나는 타이머를 사용하거나 방지하는 것을 정말로 좋아하지 않으므로 내가 한 일은 다음과 같습니다.

var el, dragged

el = $( '#some_element' );

el.on( 'mousedown', onMouseDown );
el.on( 'mouseup', onMouseUp );
el.draggable( { start: onStartDrag } );

onMouseDown = function( ) {
  dragged = false;
}

onMouseUp = function( ) {
  if( !dragged ) {
    console.log('no drag, normal click')
  }
}

onStartDrag = function( ) {
  dragged = true;
}

바위처럼 단단한..


답변

lex82의 버전이지만 .sortable ()

 start: function(event, ui){
 ui.item.find('.ui-widget-header').addClass('noclick');
 },

다음 만 필요할 수 있습니다.

 start: function(event, ui){
 ui.item.addClass('noclick');
 },

토글에 사용하는 내용은 다음과 같습니다.

$("#datasign-widgets .ui-widget-header").click(function(){
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');

}
else {
$(this).next().slideToggle();
$(this).find('.ui-icon').toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
}
});


답변

기본값을 방지하지 않고 Sasha의 대답에 대한 가능한 대안 :

var tmp_handler;
.sortable({
        start : function(event,ui){
            tmp_handler = ui.item.data("events").click[0].handler;
            ui.item.off();
        },
        stop : function(event,ui){
            setTimeout(function(){ui.item.on("click", tmp_handler)}, 300);
        },