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

67

У меня есть сортируемый список jQuery UI. Сортируемые элементы также имеют прикрепленное событие щелчка. Есть ли способ предотвратить срабатывание события 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="/jquery.min.js"></script>
<script src="/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>   
  • 2
    Теперь, когда браузеры и jqueryui успели развиться (компенсировать?), Это поведение проявляется только в Firefox (47.0). Современный Chrome и IE не sortable событие click после sortable .

10 ответов

123
Лучший ответ

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

helper : 'clone'

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

  • 1
    Леви Крейн говорит: «Трюк« помощник: клон »не работает в Chrome. Событие onclick не срабатывает никогда».
  • 0
    Это хорошо работает в моем Chrome 12. Спасибо, это намного проще.
Показать ещё 9 комментариев
13

Если у вас есть ссылка на событие click для вашего ли, вы можете отменить его в отсортированном методе обновления, а затем использовать 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="/jquery.min.js"></script>
  <script type="text/javascript" src="/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>
  • 0
    отличная реализация одного! :)
  • 0
    Это почти идеально, однако, если вы выполняете неудачное перетаскивание, оно все равно выполняет функцию щелчка. Какие-нибудь мысли? :(
3

Если вы по какой-то причине не хотите использовать трюк 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;
}
  • 0
    Откуда draggable ? Я думал, что это о sortable . Действительно, $('.draggable') для пустого списка для меня.
  • 0
    «.Sortable »- это список контейнеров, все элементы внутри него« .draggable »
2
$('.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(); } );
    }
});

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

  • 1
    Проблема в том, что если браузер никогда не запускает событие click во время перетаскивания, это предотвратит первое «настоящее» событие click
  • 0
    Для Firefox 42.0 я не могу подтвердить, что on слушателях срабатывает one слушатель. Фактически, мой on слушателе все еще вызывается раньше моего one слушателя.
1

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

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

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

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

<html>
<head> 


  <script type="text/javascript" src="/jquery.min.js"></script>
  <script type="text/javascript" src="/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

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

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

Благодаря Elte Hupkus;

helper: 'clone' 

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

$(document).ready(function() {
$("#MenuListStyle").sortable({
 helper:'clone',
 revert:true
}).disableSelection();
});
0

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

-2
$('.menu_group tbody a').click(function(){
    link = $(this).attr('href');
    window.location.href = link;
});

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню