Pertanyaan Mencegah acara klik dengan jQuery drag and drop


Saya memiliki elemen di halaman yang draggabe dengan jQuery. Elemen-elemen ini memiliki peristiwa klik yang menavigasi ke halaman lain (tautan biasa misalnya).

Apa cara terbaik untuk mencegah klik dari menembaki menjatuhkan elemen tersebut, sementara memungkinkan mengkliknya tidak menyeret dan menjatuhkan negara?

Saya memiliki masalah ini dengan elemen yang bisa diurutkan, tetapi berpikir itu baik untuk memiliki solusi untuk drag dan drop umum.

Saya telah memecahkan masalah untuk diri saya sendiri. Setelah itu menemukan solusi yang sama ada untuk Scriptaculous, tetapi mungkin seseorang memiliki cara yang lebih baik untuk mencapai itu.


76
2017-11-20 16:25


asal


Jawaban:


Sebuah solusi yang bekerja dengan baik untuk saya dan itu tidak memerlukan timeout: (ya saya agak bertele-tele ;-)

Saya menambahkan kelas penanda ke elemen saat menyeret dimulai, mis. 'noclick'. Ketika elemen dijatuhkan, peristiwa klik dipicu - lebih tepatnya jika menyeret berakhir, sebenarnya tidak harus dijatuhkan ke target yang valid. Di handler klik, saya menghapus kelas penanda jika ada, jika tidak, klik ditangani secara normal.

$('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



Solusinya adalah dengan menambahkan handler klik yang akan mencegah klik untuk menyebar pada awal drag. Dan kemudian lepaskan handler itu setelah setetes dilakukan. Tindakan terakhir harus ditunda sedikit untuk pencegahan klik untuk bekerja.

Solusi untuk bisa diurutkan:

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

Solusi untuk draggable:

...
.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



Saya ingin menambahkan ini sehingga tampaknya mencegah peristiwa klik hanya berfungsi jika peristiwa klik didefinisikan SETELAH acara yang dapat diseret atau disortir. Jika klik ditambahkan terlebih dahulu, itu akan diaktifkan pada tarik.


11
2018-03-15 13:34



Saya memiliki masalah yang sama dan mencoba beberapa pendekatan dan tidak ada yang berhasil untuk saya.

Solusi 1

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

tidak melakukan apa-apa untuk saya. Item sedang diklik setelah proses seret selesai.

Solusi 2 (oleh Tom de Boer)

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

Ini berfungsi dengan baik tetapi gagal dalam satu kasus - ketika saya akan menggunakan layar penuh onclick:

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

Solusi 3 (oleh 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);
        }
})

Ini tidak berhasil untuk saya.

Solusi 4- satu-satunya yang bekerja dengan baik

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

Yap, itu saja - urutan yang benar melakukan trik-pertama Anda perlu mengikat draggable () lalu klik () event. Bahkan ketika saya memasukkan kode toscro layar penuh di klik () acara itu masih tidak pergi ke layar penuh ketika menyeret. Sempurna untukku!


10
2018-03-28 12:44



Saya tidak begitu suka menggunakan timer atau mencegah, jadi yang saya lakukan adalah ini:

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

Rocksolid ..


9
2017-11-15 08:48



Saya menemukan bahwa menggunakan fungsi klik jQuery standar:

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

berfungsi dengan baik di UI jQuery. Peristiwa klik tidak akan dieksekusi ketika menyeret dan menjatuhkan. :)


9
2018-01-01 00:44



Versi lex82 tetapi untuk .sortable ()

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

dan Anda hanya perlu:

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

dan inilah yang saya gunakan untuk beralih:

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



Alternatif yang mungkin untuk jawaban Sasha tanpa mencegah default:

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



Di jQuery UI, elemen yang diseret diberi kelas "ui-draggable-dragging".
Karena itu kami dapat menggunakan kelas ini untuk menentukan apakah akan mengklik atau tidak, hanya menunda acara.
Anda tidak perlu menggunakan fungsi callback "start" atau "stop", cukup lakukan:

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

Ini dipicu dari "mouseup", bukan "mousedown" atau "klik" - jadi ada sedikit keterlambatan, mungkin tidak sempurna - tetapi lebih mudah daripada solusi lain yang disarankan di sini.


3
2018-03-04 18:32



Setelah membaca ini dan beberapa utas, inilah solusi yang saya gunakan.

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