Javascript jQuery UI Sortable——如何取消';拖拽/分类?

Javascript jQuery UI Sortable——如何取消';拖拽/分类?,javascript,jquery,jquery-ui,Javascript,Jquery,Jquery Ui,我有一张单子。可排序项目还附加了一个单击事件。有没有办法防止我拖动项目后触发单击事件 $().ready(函数(){ $('my#u sortable')。可排序({ update:function(){console.log('update')}, 延误:30 }); $('my#u sortable li')。单击(函数(){ console.log('click'); }); }); \my#u sortable li{ 边框:1p

我有一张单子。可排序项目还附加了一个单击事件。有没有办法防止我拖动项目后触发单击事件

$().ready(函数(){
$('my#u sortable')。可排序({
update:function(){console.log('update')},
延误:30
});    
$('my#u sortable li')。单击(函数(){
console.log('click');
});                        
});
\my#u sortable li{
边框:1px纯黑;
显示:块;
宽度:100px;
高度:100px;
背景颜色:灰色;
}

  • A
  • B
  • C

如果您有对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>

var myClick=函数(){
console.log('click');
};
$().ready(函数(){
$('my#u sortable')。可排序({
更新:函数(事件,ui){
ui.item.unbind(“单击”);
ui.item.one(“单击”,函数(事件){
console.log(“一次性单击”);
事件。stopImmediatePropagation();
$(此)。单击(myClick);
}); 
console.log('update')},
延误:30
});    
$('my#u sortable li')。单击(myClick);
});
#我亲爱的李{
边框:1px纯黑;
显示:块;
宽度:100px;
高度:100px;
背景颜色:灰色;
}
  • A
  • B
  • C

mercilor的回答对我来说有几个警告。click事件实际上发生在handle元素上,而不是排序项目本身。不幸的是,ui对象没有在更新事件(对jquery ui的功能请求?)中提供对句柄的引用。所以我得自己去拿把手。此外,我还必须调用preventDefault来停止单击操作

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

我也有同样的问题,因为我的可排序项目包含三到四个可点击的项目(数字是可变的),所以动态绑定/解除绑定似乎不是一个选项。然而,我意外地指明了

helper : 'clone'

选项,该选项在接口方面的行为与原始排序表相同,但显然不会在拖动的项上触发单击事件,从而解决了问题。它和其他任何东西一样都是一种黑客行为,但至少它又短又简单。

更简单的是,使用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="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>

$().ready(函数(){
$('my#u sortable')。可排序({
开始:函数(){
排序=真;
},
更新:函数(){
console.log('update');
排序=假;
},
延误:30
});    
$(“#我的可排序li”)。单击(函数(){
if(typeof(排序)=“未定义”| |!排序){
console.log('click');
}
});                        
});
#我亲爱的李{
边框:1px纯黑;
显示:块;
宽度:100px;
高度:100px;
背景颜色:灰色;
}
  • A
  • B
  • C

一种解决方案是使用live()而不是普通绑定,但Elte Hupkes解决方案非常棒

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

这是因为“一个侦听器”在“正常”侦听器之前被激发。因此,如果一个侦听器停止传播,它将永远不会到达您以前设置的侦听器。

我们还可以在停止事件上使用一个标志,并在单击事件上检查该标志

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;

});
感谢

我已经实现了相同的功能,下面显示了一个示例

$(document).ready(function() {
$("#MenuListStyle").sortable({
 helper:'clone',
 revert:true
}).disableSelection();
});
这个解决方案似乎对我有效。现在我可以单击可排序元素中的可单击项


注意:
“.menu\u group tbody”
.sortable()

如果您出于某种原因不想使用
助手:'clone'
技巧,这对我很有效。它取消对拖动的项目的单击事件。jQuery将类
ui可排序帮助程序
添加到拖动的元素中

$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event) {
    var cls = $(this).attr('class');
    if (cls.match('ui-sortable-helper'))
         return event.stopImmediatePropagation() || false;
}

很好地实现了一个!:)这几乎是完美的,但是,如果执行失败的拖动,它仍然会执行单击功能。有什么想法吗(上面写着:“helper:‘clone’”这个把戏在chrome中不起作用。onclick事件永远不会触发。”在Firefox 16中效果很好!谢谢你,这绝对是最好的答案!我喜欢简单的解决方案。上一个答案中的代码(选择答案)很聪明,但长期维护很有挑战性,特别是新程序员试图找出聪明的代码。我在组合可排序和放大弹出窗口时遇到问题。拖动一个元素后,弹出窗口会显示出来。这就像是上帝给我的礼物,在我与这个问题斗争了几个小时后。哇!这救了我的命!谢谢老兄!谁知道会这么简单!:d问题是如果浏览器在拖动过程中从未触发单击事件,这将阻止Firefox 42.0的第一次“真正”单击事件,我无法确认
on
侦听器在
one
侦听器之后是否触发了
on
侦听器。事实上,my
on
侦听器仍然会优先调用my
one
listener.
draggable
从何而来?我原以为这是关于
sortable
。事实上,
$('.draggable')
对我来说是一个空列表。''.sortable'是容器列表,里面的所有项目都是'.draggable',现在浏览器和jqueryui已经有了一些发展的时间(
$('.menu_group tbody a').click(function(){
    link = $(this).attr('href');
    window.location.href = link;
});
$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event) {
    var cls = $(this).attr('class');
    if (cls.match('ui-sortable-helper'))
         return event.stopImmediatePropagation() || false;
}