首页 > 解决方案 > SortableJS - 不能将项目排除在可拖动和可排序之外

问题描述

我已经在这里提交了一个问题,但只是想检查一下你是否可以在这里更快地解决这个问题。

试图将一个项目排除在可拖动之外,但不能排除在可排序之外——问题是其他元素可以放在它后面。

SortableJS Docs似乎没有排除。

这是使用 jQuery UI 的预期行为:

//jQuery UI
$("#demo .sortable").sortable({
    items: "li:not(.exclude)",
    cancel: "li.exclude"
});
$("#demo .sortable").disableSelection();

$('.add-new').click(function(){
    $(this).prev().clone().insertBefore(this);
});
h1{ font-size: 1em; margin:1em}
.sortable { list-style-type: none; margin: 0; padding: 0; width: 260px; overflow:auto; }
.sortable li { background:lightgray; text-align:center; float:left; width:50px; height:50px; margin:0.2em; padding: 0.2em; cursor:move; }
.sortable li.add-new{cursor:default; color:#959595; opacity:0.8; background: white; outline:2px dotted gray}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>

<h1>jQuery UI</h1>
<div id="demo">
    <ul class="sortable">
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
        <li class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
    </ul>
    
</div><!-- End demo -->

请注意,您永远不能在最后一个“添加新项目”之后放置项目。 这是另一个使用 jQuery UI 的示例,它区分可排序目标和放置目标,并且可以禁用其中任何一个。

到目前为止我对 SortableJS 的尝试:

// SortableJS

let mySortable = $("#demo2 .sortable").sortable({
  draggable: "li:not(.exclude)",
  animation: 250,
  forceFallback: true,
  removeCloneOnHide: true,
  touchStartThreshold: 10,

  onMove: function(evt) {
    //doesn't work
    //console.log ($(evt.dragged).index(),$('.exclude').index());
    //return $(evt.dragged).is(':last-child') ? false : true; 
  },

  onEnd: function(evt) {
    var itemEl = evt.item; // dragged HTMLElement
    if (!$('.exclude').is(':last-child')) {
      // Somewhat works but is super hacky and visually bad.
      //$('.exclude').appendTo($('.exclude').parent());  
    }
  }
});


$('.add-new').click(function(){
    $(this).prev().clone().insertBefore(this);
});
h1{ font-size: 1em; margin:1em}
.sortable { list-style-type: none; margin: 0; padding: 0; width: 260px; overflow:auto; }
.sortable li { background:lightgray; text-align:center; float:left; width:50px; height:50px; margin:0.2em; padding: 0.2em; cursor:move; }
.sortable li.add-new{cursor:default; color:#959595; opacity:0.8; background: white; outline:2px dotted gray}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>



<h1>SortableJS</h1>
<div id="demo2">
  <ul class="sortable">
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
    <li draggable="false" droppable="false" class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
  </ul>

</div>
<!-- End demo -->

我不想将“添加新项目”从可排序的 div 中取出,或者position:absolute它知道如何做到这一点吗?

谢谢!

标签: javascriptjqueryjquery-ui-sortablesortablejs

解决方案


如果您查看文档,则有一个选项过滤器:“.ignore-elements”,您可以使用它来忽略您不想被拖动的元素。然后,根据此返回 true 或 false 来检查相关目标元素是否没有排除类以取消事件。

演示代码

let mySortable = $("#demo2 .sortable").sortable({
  animation: 250,
  forceFallback: true,
  removeCloneOnHide: true,
  touchStartThreshold: 10,
  filter: ".exclude", //use this
  onMove: function(evt) {
    return evt.related.className.indexOf('exclude') === -1; //and this
  }
});


$('.add-new').click(function() {
  $(this).prev().clone().insertBefore(this);
});
h1 {
  font-size: 1em;
  margin: 1em
}

.sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 260px;
  overflow: auto;
}

.sortable li {
  background: lightgray;
  text-align: center;
  float: left;
  width: 50px;
  height: 50px;
  margin: 0.2em;
  padding: 0.2em;
  cursor: move;
}

.sortable li.add-new {
  cursor: default;
  color: #959595;
  opacity: 0.8;
  background: white;
  outline: 2px dotted gray
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>



<h1>SortableJS</h1>
<div id="demo2">
  <ul class="sortable">
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
    <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
    <li draggable="false" droppable="false" class="ui-state-default add-new exclude"><span class="ui-icon ui-icon-plus"></span>Add New Item</li>
  </ul>

</div>


推荐阅读