【问题标题】:Jqueryui sortable receive event called multiple times多次调用 Jqueryui 可排序接收事件
【发布时间】:2012-08-30 17:31:54
【问题描述】:

所以我有一个嵌套的 jqueryui 可排序和一个可拖动的项目,我可以将副本拖动到任何可排序的级别。

在这里查看 jsfiddle http://jsfiddle.net/rmossuk/JUnA7/4/

  • 产品
    • 项目1
    • 项目2
    • 项目3
      • 项目5
      • 项目6
    • 项目4

新项目

问题是当我将 NewItem 拖入嵌套的可排序 (Item3) 时,接收事件被调用 3 次。一次用于可排序的产品,出于某种原因两次用于可排序的 Item3 !!??

我需要它以便只调用 Item3 可排序接收事件而不是其他 2。

请问有人知道怎么做吗??

非常感谢

【问题讨论】:

  • 您可能想要一个更具描述性的标题。
  • 让我检查一下我的代码,我最近做了,我会尽快回复你

标签: jquery jquery-ui jquery-plugins


【解决方案1】:

该错误是由于 div.sortable 嵌套在另一个 div.sortable 中的结果,因此当您放入一个新元素时它会触发两次排序。我想出的解决方法只是计算在特定 drop 中添加的元素数量,并将一个名为“deleteMe”的类添加到重复项中。

然后您只需在排序结束时调用 $(".deleteMe").remove() 即可删除额外内容。

不理想,但似乎对我有用。 http://jsfiddle.net/JUnA7/72/

$(function() {
    var dropCount=0;
    $(".sortable").sortable({
        connectWith: ".sortable",
        cursor: 'pointer',
        receive: function(event, ui) {
            dropCount=dropCount+1;
            if(dropCount>1)
                $(ui.item).addClass("deleteMe");
            console.log(dropCount);
        },
        start: function(event, ui) {
            dropCount=0;   
            var placeholders=0;
            $(".ui-sortable-placeholder").each(function(){
                placeholders=placeholders+1;                
                if(placeholders>1)
                    $(this).height(0);
            });
        },
        stop: function(event, ui) {
            $(".deleteMe").remove();
            dropCount=0;   
        }
    });
    $(".draggable").draggable({
        handle: ".icon-move",
        connectToSortable: ".sortable",
        appendTo: "body",
        helper: 'clone',
        distance: 30
    });
});​

更新

另外,我注意到排序占位符也是重复的..所以我通过将它们的高度设置为 0px 来删除重复项。

    start: function(event, ui) {
        dropCount=0;   
        var placeholders=0;
        $(".ui-sortable-placeholder").each(function(){
            placeholders=placeholders+1;                
            if(placeholders>1)
                $(this).height(0);
        });
    }

【讨论】:

    【解决方案2】:

    嘿,如果你可以在使用 ol 和 li 上妥协的话,我稍微修改了你的代码 如果它适用于你,试试这个代码

    HTML

     <div class="container">Product1
        <ol class="sortable">
            <li>Item1</li>
            <li>Item2</li>
            <li name="to item3">Item3
               <ol>
                    <li class="inner">Item5</li>   
                    <li class="inner">Item6</li>  
               </ol>              
            </li>
            <li>Item4</li>
            <li name="new item moved">New Item</li>
        </ol>
     </div>
    

    JQUERY

     $(document).ready(function(){
        $('ol.sortable').nestedSortable(
            {
                disableNesting: 'no-nest',
                forcePlaceholderSize: true,
                handle: 'div',
                items: 'li',
                opacity: .6,
                placeholder: 'placeholder',
                revert: 250,
                tabSize: 25,
                tolerance: 'pointer',
                toleranceElement: '> div',
                connectWith: '.sortable',
                stop: function(event, ui){
                    var element = $(ui.item).attr("name");
                    var parent = $(ui.item).parent().attr("name");
                    alert(element);
                    alert(parent);
               }
            });
       });
    

    CSS

    li {
       margin-left: 10px;
       margin-top: 10px;
    }
    .inner{
       margin-left: 40px;
    }
    

    别忘了包含nestedsortable.js 和最新的Jquery

    【讨论】:

    • 如果我的代码有问题,看看这个例子,它有所有拖放的可能性jsfiddle.net/jhogervorst/Ge7eK/9希望它会有所帮助
    • 感谢您的帮助,但我需要使用 div。有没有办法用 div 做到这一点??
    • 是的,你甚至可以尝试使用 div 我没有尝试使用 div。但是你可以尝试一下并相应地更改js
    • 这很好,但我需要将项目复制到可排序的,而不仅仅是将它们从一个列表移动到另一个列表。你知道怎么做吗?谢谢
    • 复制项目是什么意思?
    【解决方案3】:

    我认为您需要防止事件传播,例如:

      event.stopPropagation();
    

    我在几个地方使用 jsfiddle 快速尝试了它,但它没有立即工作,因此您可能需要编写更多代码。

    【讨论】: