下面举例一下拖拽事件怎么用

发布时间:2025-06-24 17:58:54  作者:北方职教升学中心  阅读量:656


三、

完整代码

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>todayTask</title><scriptsrc="../js/vue.js"></script><style>.task{width:300px;height:50px;list-style-type:decimal;list-style-position:inside;cursor:grab;position:absolute;transition:top;transition-duration:0.6s;}.taskList{position:relative;display:flex;flex-direction:column;}.addTask{display:block;}</style></head><body><divclass="container"><buttonclass="addTask"@click="addTask">添加任务</button><divclass="taskList"><divclass="task"draggable="true"@dragstart.self="ondragstart($event)"@dragover.self="ondragover($event)"v-for="task in tasks":key="task.id"><span>{{task.id}}                    <inputtype="text"v-model="task.task"></span></div></div></div></body><script>document.body.addEventListener("dragover",function(ev){ev.preventDefault();})newVue({el:".container",data:{tasks:[{id:1,task:"",isDone:false}],dragDiv:"",isMoving:false},methods:{addTask(){this.tasks.push({id:this.tasks.length+1,task:"",isDone:false})vartaskList =document.getElementsByClassName("taskList")[0];taskList.style.height =this.tasks.length*50+"px"},sortDiv(divs){for(vari=0;i<divs.length;i++){divs[i].style.top =i*50+"px";}},isPreviousElements(sourse,target){//返回上一节点if(!sourse.previousElementSibling){returnfalse;}if(target.isEqualNode(sourse.previousElementSibling)){returntrue;}returnthis.isPreviousElements(sourse.previousElementSibling,target)},ondragstart(ev){this.dragDiv =ev.target;console.log("dragstart");},ondragover(ev){overDrag =ev.target;console.log(overDrag.isEqualNode(this.dragDiv));console.log(this.isMoving);if(this.isMoving ||overDrag.isEqualNode(this.dragDiv)){return;}//判断是否是前一个标签元素if(this.isPreviousElements(overDrag,this.dragDiv)){overDrag.parentNode.insertBefore(this.dragDiv,overDrag.nextElementSibling);}else{overDrag.parentNode.insertBefore(this.dragDiv,overDrag);}this.isMoving =true;constself =this;varst =setTimeout(function(){self.isMoving =false;clearTimeout(st);},600);this.sortDiv(document.querySelectorAll(".task"));}},created(){//设置ul的盒子高度vartaskList =document.getElementsByClassName("taskList")[0];taskList.style.height =this.tasks.length*50+"px";//设置每一个item的上边缘topthis.sortDiv(document.querySelectorAll(".task"));},updated(){this.sortDiv(document.querySelectorAll(".task"));}})</script></html>
问题拆解

这里可以分成两个问题,第一个是添加,第二个是拖拽。
下面举例一下拖拽事件怎么用。

二、点击按钮之后,在列表中加一个列表元素,就会重新渲染。
首先需要开始标签拖拽功能:draggable=“true” ,再添加拖拽事件。然后手动拖拽条目可以更换条目之前的位置。知识背景

3.1 vue拖拽事件

在这里插入图片描述
在这里,我们使用的是开始拖拽事件和在有效区域移动事件,为的是得到所拖拽的标签元素以及被拖动标签元素所要到达的原有标签元素的位置。
因此需要判断目标元素是否是前面的元素。

一、
添加的实现:vue技术像一个前端页面的数据管理器,它里面的 “v-for”列表渲染指令支持当列表数据增加的时候实现重新渲染增加一个条目。

<divclass="task"draggable="true"@dragstart.self="ondragstart($event)"@dragover.self="ondragover($event)"></div>

3.2 js获得同级元素节点

ele.previousSibling ele.previousElementSibling 获取同级的上下级,(前一个标签元素和后一个标签元素)ele.nextSibling ele.nextElementSibling

在这里插入图片描述

<inputid="a5"type="button"onclick="console.log('previousSibling是'+this.previousSibling);"value="e"/><!-- 这是个text对象,因为在这个标签元素前面是一个换行符 --><inputid="a6"type="button"onclick="console.log(this.previousSibling);"value="e"/><inputid="a7"type="button"onclick="console.log('previousElementSibling是'+this.previousElementSibling);"value="e"/><!-- 这是个标签元素,因为在这个js代码所取的是一个前一个标签对象 --><inputid="a8"type="button"onclick="console.log(this.previousElementSibling);"value="e"/>

在这里插入图片描述

四、场景实现

添加的实现:就是用vue中的v-for指令。场景描述

类似备忘录,点击添加按钮,多一条条目。
拖拽的实现:拖拽事件,开始的时候需要记录所拖拽的目标,拖拽经过的实现交换。
拖拽的实现:这里有两种可能性,一个是如果是往前拖拽,则所要拖拽元素放在目标元素之前;如果是往后拖拽,则所要拖拽元素放在目标元素之后。

isPreviousElements(sourse,target){//这里是判断前面是否还有元素,sourse是不是第一个元素if(!sourse.previousElementSibling){returnfalse;}//这里是判断if(target.isEqualNode(sourse.previousElementSibling)){returntrue;}returnthis.isPreviousElements(sourse.previousElementSibling,target)},

然后把标签元素放入到目标元素之前或之后。