Câu hỏi Ngăn chặn sự kiện nhấp chuột bằng cách kéo và thả jQuery


Tôi có một yếu tố trên trang đó là draggabe với jQuery. Các yếu tố này có sự kiện nhấp chuột chuyển hướng đến một trang khác (ví dụ: các liên kết thông thường).

Cách tốt nhất để ngăn nhấp chuột kích hoạt khi thả phần tử như vậy là gì, trong khi cho phép nhấp vào không phải trạng thái kéo và thả?

Tôi có vấn đề này với các yếu tố sắp xếp, nhưng nghĩ rằng nó là tốt để có giải pháp cho kéo và thả chung.

Tôi đã giải quyết được vấn đề cho bản thân mình. Sau đó phát hiện ra rằng cùng một giải pháp tồn tại cho Scriptaculous, nhưng có thể ai đó có cách tốt hơn để đạt được điều đó.


76
2017-11-20 16:25


gốc


Tương tự / trùng lặp: stackoverflow.com/questions/3486760/… - Ryan


Các câu trả lời:


Một giải pháp mà làm việc tốt cho tôi và điều đó không đòi hỏi một thời gian chờ: (có tôi là một chút pedantic ;-)

Tôi thêm một điểm đánh dấu vào phần tử khi kéo bắt đầu, ví dụ: 'noclick'. Khi phần tử bị xóa, sự kiện nhấp chuột được kích hoạt - chính xác hơn nếu kéo kết thúc, thực sự nó không phải bị bỏ vào một mục tiêu hợp lệ. Trong trình xử lý nhấp chuột, tôi xóa lớp đánh dấu nếu có, nếu không thì lần nhấp được xử lý bình thường.

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

84
2018-03-26 19:16



Hữu ích! Đã không làm việc cho tôi trong một lần, có lẽ bởi vì tôi đã rối tung trong những nỗ lực trước đó ở cùng một điều và các lớp học kết thúc trên một yếu tố khác với cái nhấp .. nhưng dù sao, tôi đã sử dụng một biến toàn cầu (mà trên này cực kỳ trang đơn giản là ok), và điều đó cũng hoạt động khá tốt. - MSpreij
Điều này dẫn tôi đến giải pháp của tôi, tôi chỉ sử dụng hàm dữ liệu jQuery thay vì một lớp. Cảm ơn. - William
nhưng trình duyệt sẽ không kích hoạt sự kiện nhấp mỗi khi bạn thả phần tử - puchu
Để lưu cài đặt lớp hoặc dữ liệu, trong trình xử lý sự kiện nhấp chuột, bạn cũng có thể sử dụng: if (! $ (This) .is ('. Ui-draggable-dragging')) {... click action} - ChrisV
Tôi thấy câu trả lời này tốt hơn nhiều: stackoverflow.com/a/13973319/336694 - Heliodor


Giải pháp là thêm trình xử lý nhấp chuột sẽ ngăn nhấp để truyền khi bắt đầu kéo. Và sau đó loại bỏ xử lý đó sau khi thả được thực hiện. Hành động cuối cùng sẽ bị trì hoãn một chút để phòng ngừa nhấp chuột hoạt động.

Giải pháp cho sắp xếp:

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

Giải pháp cho khả năng kéo:

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



Tôi thấy câu trả lời này tốt hơn nhiều: stackoverflow.com/a/13973319/336694 - Heliodor
có vẻ như điều này không thể ngăn sự kiện nhấp cho tôi, tôi sử dụng jquery 1.9.1 và jquery.ui 1.10.3 - aaron
@Heliodor đồng ý.
kỳ lạ là bạn đã trả lời câu hỏi của riêng bạn, và nó thậm chí không hoạt động, Sasha lol.
@aaron câu trả lời này dưới đây hoạt động: http://stackoverflow.com/a/4572831/119765 - lol


Tôi muốn thêm vào điều này có vẻ như ngăn sự kiện nhấp chuột chỉ hoạt động nếu sự kiện nhấp được xác định SAU sự kiện có thể kéo hoặc sắp xếp được. Nếu lần nhấp được thêm trước, nó sẽ được kích hoạt khi kéo.


11
2018-03-15 13:34



CÓ, HÃY NÀY LÀ PHƯƠNG PHÁP HIỆU QUẢ DỄ DÀNG NHẤT VÀ HIỆU QUẢ NHẤT !!! - JxAxMxIxN


Tôi đã có cùng một vấn đề và cố gắng nhiều cách tiếp cận và không ai làm việc cho tôi.

Giải pháp 1

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

không làm gì cho tôi. Mục đang được nhấp sau khi kéo xong.

Giải pháp 2 (bởi Tom de Boer)

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

Điều này hoạt động tốt nhưng không thành công trong một trường hợp - khi tôi đang dùng fullclick onclick:

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

Giải pháp 3 (bởi 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);
        }
})

Điều này không hiệu quả với tôi.

Giải pháp 4- người duy nhất làm việc tốt

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

Đúng vậy, đó là nó - thứ tự chính xác là mẹo đầu tiên bạn cần để liên kết sự kiện kéo () sau đó nhấp (). Ngay cả khi tôi đặt mã chuyển đổi toàn màn hình trong sự kiện click (), nó vẫn không chuyển sang chế độ toàn màn hình khi kéo. Hoàn hảo cho tôi!


10
2018-03-28 12:44



Chỉ có một trong đó làm việc cho tôi (trong IE11 / Edge) là giải pháp 4. Cảm ơn! - Simon


Tôi không thực sự thích sử dụng bộ đếm thời gian hoặc ngăn chặn, vì vậy những gì tôi đã làm là:

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

Sỏi đá..


9
2017-11-15 08:48



Tôi thích cái này! - aaron
Đây là giải pháp tốt nhất cho tôi. Tôi gặp sự cố khi nhận các sự kiện nhấp để hoạt động trên giao diện người dùng jquery có thể sắp xếp bằng trình duyệt web di động bằng cách sử dụng jquery.ui.touch.punch.js, nhưng điều này đã giải quyết nó khá thanh lịch. - Godsmith


Tôi thấy rằng việc sử dụng hàm nhấp chuột chuẩn của jQuery:

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

hoạt động tốt trong giao diện người dùng jQuery. Sự kiện nhấp chuột sẽ không được thực hiện khi kéo và thả. :)


9
2018-01-01 00:44



Điều này làm việc cho tôi, nhưng tôi cần xác định sự kiện nhấp chuột sau sự kiện có thể kéo được như @kasakka đã đề cập. - Aaron
Nó không hoạt động trong firefox - ccsakuweb
Xem xét rằng nó được> hai năm kể từ khi giải pháp này được đề xuất đã được gửi và rằng jQuery đã thay đổi khá một chút mà bạn xem xét khả năng trong một giải pháp trong quá khứ không còn làm việc. "Nó không hoạt động trong firefox" không xem xét bối cảnh khi tôi gửi nó .. - Norm


Phiên bản lex82 nhưng cho .sortable ()

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

và bạn chỉ có thể cần:

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

và đây là những gì tôi đang sử dụng để chuyển đổi:

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



Có vẻ như giao diện người dùng jquery gắn thêm lớp 'ui-sortable-helper' vào mục đang được sắp xếp. Vì vậy, bạn có thể bỏ qua lớp 'noclick' và chỉ cần làm nếu ($ (this) .hasClass ('ui-sortable-helper')). Hơn nữa theo cách đó - Matt De Leon


Một lựa chọn có thể có cho câu trả lời của Sasha mà không ngăn chặn mặc định:

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





Trong giao diện người dùng jQuery, các phần tử được kéo được cấp cho lớp "ui-draggable-dragging".
Do đó, chúng tôi có thể sử dụng lớp này để xác định xem có nhấp hay không, chỉ cần trì hoãn sự kiện.
Bạn không cần sử dụng chức năng gọi lại "bắt đầu" hoặc "dừng", chỉ cần thực hiện:

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

Điều này được kích hoạt từ "mouseup", thay vì "mousedown" hoặc "click" - vì vậy có một chút chậm trễ, có thể không hoàn hảo - nhưng nó dễ dàng hơn các giải pháp khác được đề xuất ở đây.


3
2018-03-04 18:32



không đẹp, nhưng nó hoạt động - Pedro Romão