拖动时候的样式怎么改_前端拖动排序实践

本文介绍了一种前端实现拖动排序的方法,从基础的DOM操作到加入动画效果,再到添加手柄以及二维空间的拖动排序。在实现过程中,详细解释了事件监听、元素交换、动画原理和优化技巧,帮助开发者掌握前端拖动排序的实现策略。
摘要由CSDN通过智能技术生成

前端的拖动排序也是一直很想实践的对象之一。

排险者露出那毫无特点的微笑说:“这很难理解吗?当生命意识到宇宙奥秘的存在时,距它最终解开这个奥秘只有一步之遥了。”看到人们仍不明白,他接着说,“比如地球生命,用了四十多亿年时间才第一次意识到宇宙奥秘的存在,但那一时刻距你们建成爱因斯坦赤道只有不到四十万年时间,而这一进程最关键的加速期只有不到五百年时间。如果说那个原始人对字宙的几分钟凝视是看到了一颗宝石,其后你们所谓的整个人类文明,不过是弯腰去拾它罢了。

复习D&D

First Thing First,最基础的事情就是复习一下D&D的API。主要是要知道拖动源和拖动目标各个事件

拖动源事件有

  • ondragstart
  • ondrag
  • ondragend

拖动目标事件有

  • ondragenter
  • ondragover
  • ondragleave
  • ondrop

有一点要注意,在可拖动元素上要设置draggable = "true",我一开始按照组件里的快捷方式就仅放置了draggable,结果连拖动的苗头都看不到。

基本DOM

 <ul id="drag" class="drag">
   <li>Item 1</li>
   <li>Item 2</li>
   <li>Item 3</li>
   <li>Item 4</li>
   <li>Item 5</li>
 </ul>

JavaScript给这些<li>元素加上draggable属性。

 const lis = document.querySelectorAll(".drag li");
 for (let i = 0; i < lis.length; i++) {
    
     lis[i].setAttribute("draggable", true);
 }

现在各<li>元素都是可拖动的了,但没有任何其他的效果。

加上样式美化元素

 ul {
    
   list-style-type: disc;
   margin-block-start: 0;
   margin-block-end: 0;
   margin-inline-start: 0;
   margin-inline-end: 0;
   padding-inline-start: 0;
 }
 li {
    
   height: 50px;
   line-height: 50px;
   border: 1px solid #aaaaaa;
   width: 200px;
   padding: 0 10px;
 }

目前的效果如下

da1df9e3cd877d2127e5d261cf5a591e.png

第一步普通排序

普通排序的目标就是能在拖动的时候实现最基本的排序功能,交换元素的位置次序。

注意,这里最合理的方式是使用事件代理,在<ul>上监听<li>冒泡来的事件,根据event.target判断事件源是哪个元素,这里我偷懒了,在每一个<li>元素上增加事件监听。

首先要把拖动源元素缓存下来。

 let draggingElement;
 for (let i = 0; i < lis.length; i++) {
    
   lis[i].setAttribute("draggable", true);
   lis[i].addEventListener("dragstart", (event) => {
    
     draggingElement = event.target;
   });
 }

接下来就是监听拖动后的变化了,思路是,当拖动某个节点进入另一个节点之后,交换两者的次序。

因为只需要第一次进入另一个节点后交换次序,所以只要监听dragenter事件即可。

 lis[i].addEventListener("dragenter", (event) => {
    
     //...
 });

此时源节点draggingElement和目标节点event.target都获得了,要做的就仅是交换两者节点的位置。要交换两者的位置,就要用到insertBeforeAPI

但注意insertBefore仅是一个单向的动作,没有insertAfter可供调用,所以在交换之前要判断一下拖动的源节点和目标节点哪个在前哪个在后。于是交换位置的代码如下

 const order = Array.from(node.parentElement.children).indexOf(node);
 //从大的序号移入到小的序号
 if (draggingElementOrder > order) {
    
   node.parentElement.insertBefore(draggingElement, node);
 }
 //从小的序号移入到大的序号
 else {
    
   //节点不是最后一个
   if (node.nextElementSibling) {
    
     node.parentElement.insertBefore(draggingElement, nod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值