jQuery UI 可排序/可拖动嵌套示例

问题描述 投票:0回答:1

我一直在使用 jQuery UI 可排序和可拖动,我正在寻找一种方法来嵌套列表项(仅第一级和第二级),具体取决于它们在列表中的位置。

我想做的简单 JSFiddle 示例:http://jsfiddle.net/picitelli/XZ4Tw/

$(".items").sortable({
    connectWith: ".items",
    placeholder: "placeholder",
    update: function(event, ui) {
        // update
    },
    sort: function(event, ui) {
        // sort
    }
});
$(".item").droppable({
    accept: ".item",
    hoverClass: "dragHover",
    drop: function( event, ui ) {
        console.log('drop');
        if (ui.position.left >= 20) {
            $(this).removeClass("first-level");
            $(this).addClass("second-level");
        } else {
            $(this).removeClass("second-level");
            $(this).addClass("first-level");
        }
    },
    over: function( event, ui ) {
        // over
    },
    activate: function( event, ui ) {
        // activate
    }
});

我希望能够拖动一个列表项并将其放在另一个列表项之前/之后,具体取决于我距列表左侧 (x) 的距离以及距底部/顶部 (y) 的距离)的列表项我放在附近,它将使该列表项成为第一级和第二级项目。例如,如果我将一个列表项拖到另一个列表项的顶部,并且我距离悬停在其上的该列表项的底部更近,而不是距离底部更远,那么如果我放下它,它将捕捉到所述列表项的底部并且是第一级项。如果我将该列表项移得更远并放下它,它就会吸附到底部并成为第二级项目。占位符也会更新,仅在悬停时调用一个类,以显示删除的列表项在实际删除之前将是第一级或第二级。

根据上面的小提琴,在 drop 方法中,我正在检查拖动的列表项距左侧有多远。如果它大于或等于 20px,我将添加一个缩进列表项的“二级”类。如果它小于 20px,我将添加一个“第一级”类,使列表项保持左对齐。仅对于左(x)计算,这是有效的,但它没有将类应用到删除的列表项,而是将它们应用到它“跳过”的列表项。我是否没有调用正确的方法来执行此操作?另外,我将如何执行这样的计算来确定列表项将捕捉到的位置,具体取决于它距我悬停的列表项的距离 (y)?

任何反馈/方向将不胜感激。

jquery jquery-ui
1个回答
9
投票

嗯,我认为你的问题看起来像是一个有趣的挑战。我知道如何去做,但不确定。所以我尝试了一下。 希望这会有用......我不确定它是否能满足您的所有需求,因此如果缺少某些内容请告诉我。 谢谢。

这是我想出的一个示例:使用

sortable
事件。

CSS

.placeholder-sub {
    background: #fff;
    border: 1px dashed #ccc;
    height: 50px;
    width: 480px;
    margin-left: 20px;
}

jQuery

$(".items").sortable({
    connectWith: ".items",
    placeholder: "placeholder",
    update: function(event, ui) {
        // update
    },
    start: function(event, ui) {
        if(ui.helper.hasClass('second-level')){
            ui.placeholder.removeClass('placeholder');
            ui.placeholder.addClass('placeholder-sub');
        }
        else{ 
            ui.placeholder.removeClass('placeholder-sub');
            ui.placeholder.addClass('placeholder');
        }
    },
    sort: function(event, ui) {
        var pos;
        if(ui.helper.hasClass('second-level')){
            pos = ui.position.left+20; 
            $('#cursor').text(ui.position.left+20);
        }
        else{
            pos = ui.position.left; 
            $('#cursor').text(ui.position.left);    
        }
        if(pos >= 32 && !ui.helper.hasClass('second-level')){
            ui.placeholder.removeClass('placeholder');
            ui.placeholder.addClass('placeholder-sub');
            ui.helper.addClass('second-level');
        }
        else if(pos < 25 && ui.helper.hasClass('second-level')){
            ui.placeholder.removeClass('placeholder-sub');
            ui.placeholder.addClass('placeholder');
            ui.helper.removeClass('second-level');
        }
    }
});

$(".items").sortable({
  connectWith: ".items",
  placeholder: "placeholder",
  update: function(event, ui) {
    // update
  },
  start: function(event, ui) {
    if (ui.helper.hasClass('second-level')) {
      ui.placeholder.removeClass('placeholder');
      ui.placeholder.addClass('placeholder-sub');
    } else {
      ui.placeholder.removeClass('placeholder-sub');
      ui.placeholder.addClass('placeholder');
    }
  },
  sort: function(event, ui) {
    var pos;
    if (ui.helper.hasClass('second-level')) {
      pos = ui.position.left + 20;
      $('#cursor').text(ui.position.left + 20);
    } else {
      pos = ui.position.left;
      $('#cursor').text(ui.position.left);
    }
    if (pos >= 32 && !ui.helper.hasClass('second-level')) {
      ui.placeholder.removeClass('placeholder');
      ui.placeholder.addClass('placeholder-sub');
      ui.helper.addClass('second-level');
    } else if (pos < 25 && ui.helper.hasClass('second-level')) {
      ui.placeholder.removeClass('placeholder-sub');
      ui.placeholder.addClass('placeholder');
      ui.helper.removeClass('second-level');
    }
  }
});
$(".item").droppable({
  accept: ".item",
  hoverClass: "dragHover",
  drop: function(event, ui) {
    /*console.log('drop');
    if (ui.position.left >= 20) {
        $(this).removeClass("first-level");
        $(this).addClass("second-level");
    } else {
        $(this).removeClass("second-level");
        $(this).addClass("first-level");
    }*/
  },
  over: function(event, ui) {
    // over
  },
  activate: function(event, ui) {
    // activate
  }
});
.items {
  list-style: none outside none;
  margin-bottom: 20px;
  padding: 0;
  width: 480;
}

.item {
  background: #fff;
  border: 1px solid #ddd;
  cursor: move;
  height: 50px;
  line-height: 50px;
  padding: 0 10px;
  width: 480px;
}

.second-level {
  margin-left: 20px;
  width: 460px;
}

.dragHover {
  border-color: blue;
  color: blue;
}

.placeholder {
  background: #fff;
  border: 1px dashed #ccc;
  height: 50px;
  width: 500px;
}

.placeholder-sub {
  background: #fff;
  border: 1px dashed #ccc;
  height: 50px;
  width: 480px;
  margin-left: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.14.1/jquery-ui.min.js" integrity="sha512-MSOo1aY+3pXCOCdGAYoBZ6YGI0aragoQsg1mKKBHXCYPIWxamwOE7Drh+N5CPgGI5SA9IEKJiPjdfqWFWmZtRA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<label>Cursor At:</label><label id="cursor"></label>

<ul class="items">
  <li class="item first-level">Item #1</li>
  <li class="item second-level">Item #2</li>
  <li class="item second-level">Item #3</li>
  <li class="item first-level">Item #4</li>
  <li class="item first-level">Item #5</li>
</ul>

<ul class="items">
  <li class="item">Add new item</li>
</ul>

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.