programing

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

muds 2023. 10. 28. 08:21
반응형

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

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

드래그 앤 드롭 상태가 아닌 상태에서 클릭을 허용하면서 해당 요소를 드롭할 때 발생하는 클릭을 방지하는 가장 좋은 방법은 무엇입니까?

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

저는 그 문제를 스스로 해결했습니다.그 후 저는 Scriptaculous를 위한 동일한 솔루션이 존재하지만, 이를 달성하기 위해 누군가가 더 나은 방법을 가지고 있다는 것을 알게 되었습니다.

저에게 잘 적용되었고 시간 초과가 필요 없는 솔루션: (네, 저는 약간 현학적입니다;-)

드래그 시작 시 요소에 마커 클래스를 추가합니다(예: 'nocclick').요소가 삭제되면 클릭 이벤트가 트리거됩니다. 보다 정확하게는 드래그가 종료되는 경우, 실제로는 유효한 대상에 삭제할 필요가 없습니다.클릭 핸들러에서 마커 클래스가 있으면 제거하고 그렇지 않으면 클릭이 정상적으로 처리됩니다.

$('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 (톰 드 보어 작)

$('.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 (사샤 야노베츠 작)

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

네, 맞습니다. 올바른 순서가 트릭을 수행합니다. 먼저 드래그 가능()을 바인딩한 다음() 이벤트를 클릭해야 합니다.클릭() 이벤트에 전체 화면 전환 코드를 넣어도 드래그할 때 전체 화면으로 전환되지 않습니다.나한테 딱!

여기에 드래그 가능하거나 정렬 가능한 이벤트 뒤에 클릭 이벤트가 정의된 경우에만 클릭 이벤트를 방지할 수 있는 것처럼 보인다는 점을 덧붙이고 싶습니다.클릭을 먼저 추가하면 드래그 시 활성화됩니다.

저는 타이머를 사용하거나 방지하는 것을 별로 좋아하지 않습니다. 그래서 제가 한 일은 다음과 같습니다.

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

디폴트를 방지하지 않고 사샤의 대답을 대신할 수 있는 대안:

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

jQuery UI에서 드래그하는 요소에는 "ui-dragable-draggable-dragging" 클래스가 부여됩니다.
따라서 이 클래스를 사용하여 클릭 여부를 결정할 수 있으며 이벤트를 지연시키기만 하면 됩니다.
"시작" 또는 "중지" 콜백 기능을 사용할 필요 없이 다음 작업만 수행하면 됩니다.

$('#foo').on('mouseup', function () {
    if (! $(this).hasClass('ui-draggable-dragging')) {
        // your click function
    }
});

이는 "마우스 다운" 또는 "클릭"이 아닌 "마우스 업"에서 트리거되므로 약간의 지연이 발생할 수 있으며 완벽하지 않을 수도 있습니다. 그러나 여기서 제안하는 다른 솔루션보다 쉽습니다.

제 경우에는 이렇게 작동했습니다.

$('#draggable').draggable({
  start: function(event, ui) {
    $(event.toElement).one('click', function(e) { e.stopPropagation(); });
  }
});

이 글을 읽고 몇 가지 실타래를 한 끝에 이것이 해결책이 되었습니다.

var dragging = false;
$("#sortable").mouseover(function() {
    $(this).parent().sortable({
        start: function(event, ui) {
            dragging = true;
        },
        stop: function(event, ui) {
            // Update Code here
        }
    })
});
$("#sortable").click(function(mouseEvent){
    if (!dragging) {
        alert($(this).attr("id"));
    } else {
        dragging = false;
    }
});

가장 쉽고 강력한 솔루션?드래그 가능한 부분 위에 투명한 요소를 만들기만 하면 됩니다.

.click-passthrough {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: transparent;
}

element.draggable({        
        start: function () {

        },
        drag: function(event, ui) {
            // important! if create the 'cover' in start, then you will not see click events at all
                  if (!element.find('.click-passthrough').length) {
                      element.append("<div class='click-passthrough'></div>");
                  }
        },
        stop: function() {
          // remove the cover
          element.find('.click-passthrough').remove();
        }
    });

시작 이벤트에서 event.preventDefault(); 를 사용하여 링크를 비활성화하고 drag stoped 이벤트 또는 unbind를 사용하여 드롭 이벤트에서 링크를 다시 활성화하시겠습니까?

위에 제시된 답변에 추가하기 위해 약간의 주름이 있습니다.SalesForce 요소가 포함된 div를 드래그 가능하게 만들어야 했는데, SalesForce 요소는 visualForce gobbledook을 통해 html에 정의된 on click action이 있습니다.

분명히 이는 "끌기 동작 후 클릭 동작 정의" 규칙을 위반하는 것이므로, 저는 해결책으로 SalesForce 요소의 동작을 "onDblClick" 트리거되도록 재정의하고 컨테이너 디브에 이 코드를 사용했습니다.

$(this).draggable({
        zIndex: 999,
        revert: true,
        revertDuration: 0,
        start: function(event, ui) {
                   $(this).addClass('noclick');
                }
});

$(this).click(function(){
    if( $(this).hasClass('noclick'))
    {
        $(this).removeClass('noclick');
    }
    else
    {
        $(this).children(":first").trigger('dblclick');
    }
});

부모의 클릭 이벤트는 기본적으로 자식 요소를 두 번 클릭해야 하는 필요성을 숨기고 사용자 환경을 그대로 유지합니다.

나는 이렇게 노력했습니다.

var dragging = true; 

$(this).click(function(){
  if(!dragging){
    do str...
  }
});

$(this).draggable({
  start: function(event, ui) {
      dragging = true;
  },

  stop: function(event, ui) {
      setTimeout(function(){dragging = false;}, 300);
  }

});

나는 옵션 객체에서 도우미를 전달하는 것을 도왔습니다.

.sortable({
   helper : 'clone', 
   start:function(), 
   stop:function(),
   .....
});

끌리는 돔 요소를 복제하는 것이 이벤트의 거품을 막은 것 같습니다.나는 어떤 이벤트로도 피할 수 없었습니다 전파, 거품 등등.이것이 제가 해결할 수 있는 유일한 방법이었습니다.

온마우스 다운과 온마우스업 이벤트는 제 소규모 프로젝트 중 하나에서 효과가 있었습니다.

var mousePos = [0,0];
function startClick()
{
    mousePos = [event.clientX,event.clientY];
}
        
function endClick()
{
    if ( event.clientX != mousePos[0] && event.clientY != mousePos[1] )
    {
        alert( "DRAG CLICK" );
    }
    else
    {
        alert( "CLICK" );
    }
}
<img src=".." onmousedown="startClick();" onmouseup="endClick();" />

네, 알고 있습니다.가장 깨끗한 방법은 아니지만, 당신은 이해합니다.

언급URL : https://stackoverflow.com/questions/1771627/preventing-click-event-with-jquery-drag-and-drop

반응형