Сортируемый пользовательский интерфейс jQuery - Как отменить событие нажатия на элемент, который перетаскивается / сортируется? - PullRequest
66 голосов
/ 04 июня 2009

У меня есть список jQuery UI Sortable . Сортируемые элементы также имеют прикрепленное событие щелчка. Есть ли способ предотвратить срабатывание события click после перетаскивания элемента?

$().ready( function () { 
 $('#my_sortable').sortable({
   update: function() { console.log('update') },
   delay: 30
 });    

 $('#my_sortable li').click(function () {    
   console.log('click');
 });                        

});
#my_sortable li {
          border: 1px solid black;
          display: block;
          width: 100px;
          height: 100px;    
          background-color: gray;
        }
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>

<ul id="my_sortable">                 
  <li id="item_1">A</li>
  <li id="item_2">B</li>
  <li id="item_3">C</li>
</ul>   

Ответы [ 10 ]

132 голосов
/ 05 июня 2010

У меня была такая же проблема, и так как мои сортируемые элементы содержали три или четыре активируемых элемента (и их число было переменным), связывание / открепление их на лету не представлялось возможным. Тем не менее, случайно я указал

helper : 'clone'
Параметр

, который ведет себя идентично исходной сортируемости с точки зрения интерфейса, но, по-видимому, не запускает события щелчка на перетаскиваемом элементе и, таким образом, решает проблему. Это такой же взлом, как и все остальное, но, по крайней мере, он короткий и легкий ..

13 голосов
/ 04 июня 2009

Если у вас есть ссылка на событие click для вашего li, вы можете отсоединить его в методе сортируемого обновления, а затем использовать Event / one для его повторного связывания. Перед повторной привязкой распространение события может быть остановлено, что не позволяет запустить исходный обработчик щелчков.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head> 


  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>

  <script type="text/javascript" charset="utf-8">
    var myClick = function () {
        console.log('click');
    };

    $().ready( function () { 

       $('#my_sortable').sortable({
         update: function(event, ui) { 
            ui.item.unbind("click");
            ui.item.one("click", function (event) { 
                console.log("one-time-click"); 
                event.stopImmediatePropagation();
                $(this).click(myClick);
            }); 
            console.log('update') },
         delay: 30
       });    


       $('#my_sortable li').click(myClick);                        

     });
  </script>

  <style type="text/css" media="screen">
    #my_sortable li {
      border: 1px solid black;
      display: block;
      width: 100px;
      height: 100px;    
      background-color: gray;
    }
  </style>

</head>
<body>

      <ul id="my_sortable">                 
        <li id="item_1">A</li>
        <li id="item_2">B</li>
        <li id="item_3">C</li>
      </ul>   

</body>
</html>
3 голосов
/ 17 ноября 2015

Если вы по какой-то причине не хотите использовать трюк helper:'clone', это сработало для меня. Он отменяет событие щелчка по перетаскиваемому элементу. jQuery добавляет класс ui-sortable-helper к перетаскиваемому элементу.

$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event) {
    var cls = $(this).attr('class');
    if (cls.match('ui-sortable-helper'))
         return event.stopImmediatePropagation() || false;
}
2 голосов
/ 20 декабря 2012
$('.selector').draggable({
    stop: function(event, ui) {
        // event.toElement is the element that was responsible
        // for triggering this event. The handle, in case of a draggable.
        $( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
    }
});

Это работает, потому что "one-listeners" запущены перед "normal" listeners Так что, если один слушатель останавливает распространение, он никогда не достигнет ваших ранее установленных слушателей.

1 голос
/ 08 ноября 2013

Мы также можем использовать флажок на событии stop и проверять этот флажок на событии click.

var isSortableCalled = false;

$('#my_sortable').sortable({
         stop: function(event, ui){
              isSortableCalled = true;
         },
         update: function() { console.log('update') },
         delay: 30
});

$('#my_sortable li').click(function () {    
       if(!isSortableCalled){
            console.log('click');
       }
       isSortableCalled = false;

});
1 голос
/ 16 сентября 2010

Проще, используйте переменную, чтобы узнать, когда элемент сортируется ...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head> 


  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>

  <script type="text/javascript" charset="utf-8">
    $().ready( function () {    
       $('#my_sortable').sortable({
         start: function() {
            sorting = true;
         },
         update: function() {
            console.log('update');
            sorting = false;
         },
         delay: 30
       });    


       $('#my_sortable li').click(function () {
         if (typeof(sorting) == "undefined" || !sorting) {
            console.log('click');
         }
       });                        

     });
  </script>

  <style type="text/css" media="screen">
    #my_sortable li {
      border: 1px solid black;
      display: block;
      width: 100px;
      height: 100px;    
      background-color: gray;
    }
  </style>

</head>
<body>

      <ul id="my_sortable">                 
        <li id="item_1">A</li>
        <li id="item_2">B</li>
        <li id="item_3">C</li>
      </ul>   

</body>
</html>
1 голос
/ 13 января 2010

Ответ от mercilor сработал для меня в нескольких оговорках. Событие click было фактически на элементе handle, а не на самом отсортированном элементе. К сожалению, объект пользовательского интерфейса не дает ссылку на дескриптор в событии обновления (запрос функции в jquery пользовательский интерфейс?). Таким образом, я должен был взять ручку сам. Кроме того, мне также пришлось вызывать protectDefault, чтобы остановить действие щелчка.

update: function(ev, ui) {
    var handle = $(ui.item).find('h3');
    handle.unbind("click");
    handle.one("click", function (event) {
                            event.stopImmediatePropagation();
                            event.preventDefault();
                            $(this).click(clickHandler);
                        });
    // other update code ...
0 голосов
/ 19 февраля 2015
$('.menu_group tbody a').click(function(){
    link = $(this).attr('href');
    window.location.href = link;
});

Это решение, похоже, работает на меня. Теперь я могу нажимать на интерактивные элементы внутри сортируемых элементов.

Примечание: ".menu_group tbody" is .sortable();

0 голосов
/ 31 декабря 2014

Благодаря Эльте Хупкус ;

helper: 'clone' 

Я реализовал то же самое, и пример показан ниже.

$(document).ready(function() {
$("#MenuListStyle").sortable({
 helper:'clone',
 revert:true
}).disableSelection();
});
0 голосов
/ 04 июня 2011

Одним из решений является использование live () вместо обычного связывания, но решение Elte Hupkes не дает результатов !!!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...