Frage Klickereignis mit jQuery drag and drop verhindern


Ich habe auf der Seite ein Element, das mit jQuery draggabe ist. Diese Elemente haben Klick-Ereignisse, die zu einer anderen Seite navigieren (zum Beispiel gewöhnliche Links).

Was ist der beste Weg, zu verhindern, dass der Klick ausgelöst wird, wenn man ein solches Element löscht, während man darauf klicken darf, dass man nicht drag and drop geht?

Ich habe dieses Problem mit sortierbaren Elementen, aber denke, es ist gut, eine Lösung für das allgemeine Ziehen und Ablegen zu haben.

Ich habe das Problem für mich selbst gelöst. Danach fand dieselbe Lösung existiert für Scriptaculous, aber vielleicht hat jemand einen besseren Weg, das zu erreichen.


76
2017-11-20 16:25


Ursprung


Antworten:


Eine Lösung, die für mich gut funktioniert und keine Zeitüberschreitung erfordert: (ja, ich bin ein bisschen pedantisch ;-)

Ich füge dem Element eine Markierungsklasse hinzu, wenn das Ziehen beginnt, z. 'noclick'. Wenn das Element gelöscht wird, wird das click -Ereignis ausgelöst - genauer gesagt, wenn das Ziehen endet, muss es nicht auf ein gültiges Ziel fallen gelassen werden. Im Click-Handler entferne ich die Marker-Klasse, falls vorhanden, ansonsten wird der Klick normal gehandhabt.

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

83
2018-03-26 19:16



Die Lösung besteht darin, einen Klick-Handler hinzuzufügen, der verhindert, dass sich der Klick beim Start des Ziehens ausbreitet. Und dann entferne diesen Handler, nachdem der Drop ausgeführt wurde. Die letzte Aktion sollte etwas verzögert werden, damit die Klickprävention funktioniert.

Lösung für sortierbare:

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

Lösung für ziehbare:

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

38
2017-11-20 16:26



Ich möchte hinzufügen, dass es scheint zu verhindern, dass das Klickereignis nur funktioniert, wenn das Klickereignis nach dem ziehbaren oder sortierbaren Ereignis definiert ist. Wenn der Klick zuerst hinzugefügt wird, wird er beim Ziehen aktiviert.


11
2018-03-15 13:34



Ich hatte das gleiche Problem und versuchte mehrere Ansätze und keiner arbeitete für mich.

Lösung 1

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

tut nichts für mich. Nach dem Ziehen wird auf das Objekt geklickt.

Lösung 2 (von Tom de Boer)

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

Dies funktioniert gut, aber in einem Fall fehlschlägt - wenn ich Fullscreen onclick ging:

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

Lösung 3 (von Sascha 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);
        }
})

Das funktioniert nicht für mich.

Lösung 4- die einzige, die gut funktionierte

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

Ja, das ist es - die richtige Reihenfolge macht den Trick - zuerst müssen Sie ziehbare () und dann click () Ereignisse binden. Selbst wenn ich den Vollbild-Umschaltcode in das click () -Ereignis setze, ging er immer noch nicht in den Vollbildmodus, wenn er gezogen wurde. Perfekt für mich!


10
2018-03-28 12:44



Ich mag es nicht, Timer zu verwenden oder zu verhindern, also was ich getan habe, ist folgendes:

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

Steinschlag ..


9
2017-11-15 08:48



Ich habe festgestellt, dass mit der Standard-jQuery-Klick-Funktion:

$("#element").click(function(mouseEvent){ // click event }); 

funktioniert gut in jQuery UI. Das Klickereignis wird nicht beim Ziehen und Ablegen ausgeführt. :)


9
2018-01-01 00:44



lex82s Version aber für .sortable ()

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

und du brauchst vielleicht nur:

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

und hier ist, was ich für den Schalter verwende:

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

3
2018-01-10 20:24



Eine mögliche Alternative für Sashas Antwort, ohne den Default zu verhindern:

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

3
2017-11-09 19:10



In der jQuery UI erhalten Elemente, die gezogen werden, die Klasse "ui-draggable-dragging".
Wir können daher diese Klasse verwenden, um zu bestimmen, ob geklickt werden soll oder nicht, nur das Ereignis zu verzögern.
Sie müssen nicht die Callback-Funktionen "Start" oder "Stop" verwenden, sondern einfach:

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

Dies wird von "mouseup" statt "mousedown" oder "click" ausgelöst - es gibt also eine kleine Verzögerung, vielleicht nicht perfekt - aber es ist einfacher als andere hier vorgeschlagene Lösungen.


3
2018-03-04 18:32



Nach dem Lesen dieser und ein paar Threads war dies die Lösung, mit der ich ging.

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

1
2017-09-09 17:11



Haben Sie versucht, den Link mit event.preventDefault () zu deaktivieren? im Start-Event und wieder aktivieren es im Drag stopped Event oder Drop-Ereignis mit Unbind?


0
2017-11-20 16:29