78

Tôi có các phần tử trên trang có thể kéo được bằng jQuery. Do các yếu tố này có nhấp vào sự kiện mà điều 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 bắn vào phần tử như vậy trong khi cho phép nhấp vào nó không bị kéo và thả trạng thái là gì?

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

Tôi đã tự giải quyết vấn đề. Sau đó tôi thấy rằng giải pháp tương tự tồn tại cho Scriptacificent , nhưng có lẽ ai đó có cách tốt hơn để đạt được điều đó.

|
38

Giải pháp là thêm trình xử lý nhấp chuột sẽ ngăn nhấp để lan 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 nên được trì hoãn một chút để ngăn chặn nhấp chuột hoạt động.

Giải pháp cho việc 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 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);
        }
...
})
|
86

Một giải pháp hiệu quả với tôi và không cần thời gian chờ: (vâng tôi hơi khoa trương ;-)

Tôi thêm một lớp đánh dấu vào phần tử khi bắt đầu kéo, ví dụ 'noclick'. Khi phần tử bị loại bỏ, sự kiện nhấp được kích hoạt - chính xác hơn là nếu việc kéo kết thúc, thực tế nó không phải được thả vào một mục tiêu hợp lệ. Trong trình xử lý nhấp chuột, tôi loại bỏ lớp đánh dấu nếu có, nếu không thì nhấp chuột đượ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
    }
});
|
11

Tôi có cùng một vấn đề và đã thử nhiều cách tiếp cận và không có cách nào hiệu quả với 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 này đang được nhấp sau khi kéo xong.

Giải pháp 2 (của Tom de Boer)

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

Điều này chỉ hoạt động tốt nhưng thất bại trong một trường hợp - khi tôi đang ở chế độ toàn màn hình onclick:

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

Giải pháp 3 (của 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 làm việc cho tôi.

Giải pháp 4- chỉ có một giải pháp tốt

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

Đúng, đó là - thứ tự đúng thực hiện thủ thuật - trước tiên bạn cần liên kết sự kiện draggable () sau đó nhấp (). Ngay cả khi tôi đặt mã bật tắt 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!

|
11

Tôi muốn thêm vào điều này rằng dường như việc ngăn chặn sự kiện nhấp 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 có thể sắp xếp. Nếu lần nhấp được thêm vào trước, nó sẽ được kích hoạt khi kéo.

|
9

Tôi thấy rằng bằng cách sử dụng chức năng nhấp chuột jQuery tiêu chuẩn:

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

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

|
  • 1

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

    – Ngô Dạ Thy 14:45:15 08/11/2011
  • 1

    Nó không hoạt động trong firefox

    – Ngô Ly Châu 11:12:02 09/07/2013
  • 1

    Xem xét rằng đã hai năm kể từ khi giải pháp đề xuất này được gửi và jQuery đã thay đổi khá nhiều mà bạn cho rằng khả năng trong một giải pháp trước đây không còn hoạt động. "Nó không hoạt động trong firefox" không xem xét bối cảnh khi tôi gửi nó ..

    – Lý Nhã Trang 19:36:54 21/07/2013
8

Tôi thực sự không thích sử dụng bộ hẹn giờ 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 đá..

|
  • 1

    Tôi thích cái này!

    – Ngô Dạ Thy 14:08:02 03/09/2013
  • 1

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

    – Ngô Ly Châu 20:11:05 18/05/2014
3

Trong jQuery UI, các phần tử được kéo được đưa ra lớp "ui-draggable-dragging".
Do đó, chúng ta có thể sử dụng lớp này để xác định có nên nhấp hay không, chỉ cần trì hoãn sự kiện.
Bạn không cần sử dụng các hàm gọi lại "bắt đầu" hoặc "dừng", chỉ cần làm:

$('#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ễ hơn các giải pháp khác được đề xuất ở đây.

|
3

Một cách khác có thể 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

phiên bản của lex82 nhưng dành cho .sortable ()

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

và bạn có thể chỉ 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");
}
});
|
  • 1

    Dường như UI jquery nối thêm lớp 'ui-sortable-helper' vào mục đang được sắp xếp. Vì vậy, bạn có thể loại bỏ lớp 'noclick' và chỉ cần làm nếu ($ (này) .hasClass ('ui-sortable-helper')). Tuyệt vời hơn theo cách đó

    – Ngô Dạ Thy 15:55:20 14/03/2012
1

Sau khi đọc qua điều này và một vài chủ đề, đây là giải pháp tôi đã thực hiện.

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

Trong trường hợp của tôi, nó hoạt động như thế này:

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

Tôi đã thử như thế này:

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

});
|
0

Chỉ cần một chút nếp nhăn để thêm vào các câu trả lời ở trên. Tôi đã phải tạo một div có chứa phần tử SalesForce có thể kéo được, nhưng phần tử SalesForce có một hành động onclick được xác định trong html thông qua một số gobbledigook VisualForce.

Rõ ràng điều này vi phạm quy tắc "xác định hành động nhấp sau hành động kéo", do đó, một cách giải quyết tôi đã xác định lại hành động của phần tử SalesForce được kích hoạt "onDblClick" và sử dụng mã này cho div container:

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

Sự kiện nhấp chuột của cha mẹ về cơ bản che giấu nhu cầu nhấp đúp vào phần tử con, giữ nguyên trải nghiệm người dùng.

|
0

Bạn đã thử vô hiệu hóa liên kết bằng event.preventDefault (); trong sự kiện bắt đầu và kích hoạt lại nó trong sự kiện kéo dừng hoặc thả sự kiện bằng cách sử dụng unbind?

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.