如何让人们将 LI 拖放到列表中的特定位置? (console.log 问题)

Posted

技术标签:

【中文标题】如何让人们将 LI 拖放到列表中的特定位置? (console.log 问题)【英文标题】:How can I let people drag and drop LI's to a specific place in a list? (console.log issues) 【发布时间】:2018-01-23 18:42:19 【问题描述】:

我面临两个问题,一个是目标,另一个是无法从 console.log() 调用中获取信息。

我们先看目标:

我在https://jsfiddle.net/L7sbhzzj/ 有一个 JSfiddle,用于我正在进行的项目。我正在处理的代码是:

jQuery('.collection').droppable(
    
    'accept': '.collection > li',
    'drop': function(e, ui)
        
        console.log('Reached here!');
        console.log(this);
        jQuery('#selection').append(ui.draggable);
        
    );

本质上,我希望人们能够将元素拖放到列表中的特定位置。因此,在 JSfiddle 中,您可以将“Fiction”拖到右侧,但如果这样做然后将“Nonfiction”拖到“Nonfiction”上,“Nonfiction”只会添加到末尾;您不能随后将“非小说”拖动到“小说”的上方和之前。

我想避免重新发明***;我想有一些标准模式,比如“将被丢弃的 LI 放在目标 UL 的 LI 之前,它与页面顶部的距离最短,但仍等于或大于被丢弃的 LI 到页面顶部的距离。”

现在回到我面临的另一个问题:jQuery('#selection').append(ui.draggable); 正在工作或其他东西正在做同等的工作,但我的 console.log() 似乎都没有被报告。

我对如何实现某些东西有一些想法,但是当我在做某事时,最好自省并获得 console.log()s 的诊断输出。

'drop' 是否生效?它是否以其他方式工作?如何获取对象被拖放到哪个元素之类的信息?

--编辑--

我意识到我要求的是我想要的一方面。我希望人们能够将物品 XYZ 从一个容器带到另一个容器,然后在他们改变主意时再拿回来。 Snowmonkey 的解决方案非常适合可排序的正确列表。但是,下面的适配失败了,可能是因为我调用了两个不兼容的增强:

jQuery(function()

jQuery('#selection').sortable(
    
    );
jQuery('li', jQuery('#source')).draggable(
    
    'connectToSortable': '#selection',
    'cancel': 'a.ui-icon',
    'revert': 'invalid',
    'containment': 'document',
    'cursor': 'move'
    );
jQuery('#source').sortable(
    
    );
jQuery('li', jQuery('#selection')).draggable(
    
    'connectToSortable': '#selection',
    'cancel': 'a.ui-icon',
    'revert': 'invalid',
    'containment': 'document',
    'cursor': 'move'
    );

我怎样才能得到 Snowmonkey 答案的完全双向变化?

谢谢,

【问题讨论】:

【参考方案1】:

所以您想将可拖动对象连接到可排序对象?这是一个简单的方法。完全摆脱 droppable,只需将“connectToSortable”规则添加到您的可拖动对象。因此,#selection 仍然是可排序的,而#source 仍然是可拖动的,可以拖放到 #source 上的任何位置。

jQuery(function() 

  $(".collection").sortable(
  );
  
  jQuery('li', jQuery('.collection')).draggable(
    'connectToSortable': '.collection',
    'cancel': 'a.ui-icon',
    'revert': 'invalid',
    'containment': 'document',
    'cursor': 'move'
  );
);
body 
  background-color: #ccc;
  font-family: Verdana, Georgia;


div.main 
  margin-left: auto;
  margin-right: auto;
  width: 440px;


div.table 
  display: table;
  width: 440px;


div.td 
  display: table-cell;
  width: 50%;


div.tr 
  display: table-row;


ul.collection 
  background-color: white;
  list-style: none;
  padding-left: 0;
  min-height: 100px;
  padding-left: 0;
  width: 200px;


ul.collection > li 

ul#selection 
  float: right;


ul#source 
  float: left;
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="main">
  <div class="table">
    <div class="tr">
      <div class="td">
        <ul id="source" class="collection">
          <li>Everything</li>
          <li>Nonfiction</li>
          <li>Fiction</li>
          <li>Poetry</li>
        </ul>
      </div>
      <div class="td">
        <ul id="selection" class="collection">
          <li>Empty</li>
        </ul>
      </div>
    </div>
  </div>

</div>

所以我更新了上面的帖子,使其在两个方向都有效。我没有使用这两个元素的 ID,而是使用了它们共有的类。两个 .collection 元素都是可排序的,并且都是 connectToSortable .collection 元素。希望对您有所帮助!

【讨论】:

谢谢(对于我的背景,你是怎么把你的答案格式化成这种格式的?太可爱了!)。这具有可根据需要排序的右侧,但正如现在在问题中编辑的那样,我希望该功能可以双向工作。您是否愿意重新阅读扩展的问题并说明如何使其双向工作?谢谢, @JonathanHayward,我更新了上面的代码块来做你想要的。我使用 ID 使其明确,但如果您希望它双向工作,只需使用类而不是 ID。当我回答时,我点击了文本输入字段上方的“代码”按钮来创建格式漂亮的工作代码。 ;) 好的;谢谢。有一个 CSS 注释我想知道您是否有评论(我应该问一个单独的问题吗?):如果任一 UL 为空,则它会像 cjshayward.com/wp-content/project/staggered.png 那样交错;在我看来,它们是交错的,因此一个的顶部与另一个的底部齐平,并且将最后一个元素从左向右传输会产生令人讨厌的闪烁效果。我想要的,以及当它们都为非空时会发生什么,是让它们都一直在顶部齐平,如cjshayward.com/wp-content/project/flush.png。有什么方法可以在 CSS 中强制执行此操作? 最简单的方法?像我在上面所做的那样更改 CSS:一个向左浮动,另一个向右浮动。因此,它们彼此独立移动。或者,令人高兴的是,它们根本不动。【参考方案2】:

您只需使用可排序的 jquery ui 即可实现您想要的。如果您想在将项目添加到选择时收到通知,您可以监听接收事件。

jQuery(function()

 jQuery( "#source" ).sortable(
   connectWith: "#selection",
).disableSelection();

jQuery("#selection").sortable(
    receive: function() 
    console.log("changed");
   
)
);

【讨论】:

以上是关于如何让人们将 LI 拖放到列表中的特定位置? (console.log 问题)的主要内容,如果未能解决你的问题,请参考以下文章

如何将项目拖放到 react-dnd 中的空白部分?

将列表中的元素拖放到单独的块中

在特定鼠标位置拖放到 TextBox - 显示插入符号或位置指示符

如何将下拉列表视图项目拖放到另一个列表视图

将列表视图的列表项拖放到另一个列表视图列表项

在 RecyclerView 中的特定位置拖放停止