draggable拖动input输入框不能选中_前端拖动排序实践

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

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

复习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;
 }

目前的效果如下

b9d1788c76ab3294bbc1726d25487ec6.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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想在拖动两个输入框时交换它们的值,你可以通过使用 `dragstart`、`dragover` 和 `drop` 事件来实现。 首先,你需要为两个输入框添加 `draggable` 属性,以便它们可以被拖动。在 `dragstart` 事件中,你需要设置数据传输,以便在拖动时可以传递数据。在这里,你可以将输入框的值存储在 `dataTransfer` 对象中。 ``` <input id="input1" draggable="true" ondragstart="drag(event)" type="text"> <input id="input2" draggable="true" ondragstart="drag(event)" type="text"> <script> function drag(event) { event.dataTransfer.setData("value", event.target.value); } </script> ``` 然后,你需要为每个输入框添加 `dragover` 和 `drop` 事件,以便在拖动时进行交换。在 `dragover` 事件中,你需要调用 `event.preventDefault()`,以便在拖动时可以放置数据。在 `drop` 事件中,你需要获取存储在 `dataTransfer` 对象中的值,并将它们交换。 ``` <input id="input1" draggable="true" ondragstart="drag(event)" ondragover="allowDrop(event)" ondrop="drop(event)" type="text"> <input id="input2" draggable="true" ondragstart="drag(event)" ondragover="allowDrop(event)" ondrop="drop(event)" type="text"> <script> function allowDrop(event) { event.preventDefault(); } function drop(event) { var value1 = document.getElementById("input1").value; var value2 = document.getElementById("input2").value; document.getElementById("input1").value = value2; document.getElementById("input2").value = value1; } </script> ``` 这样,当你拖动一个输入框并将其放置在另一个输入框上时,它们的值将被交换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值