拖拽牛逼,轻松实现一个自由拖拽的组件
如何使元素支持拖动
实现组件的自由拖动的核心就是 html5
中新添加的全局属性 draggable
属性,该属性规定了元素是否可进行拖动。属性值如下所示:
true:规定元素的可拖动的
false:规定元素不可拖动
auto:使用浏览器的默认行为
当我们在元素元素标签中添加 draggable
属性时,该元素就可以进行拖动操作了。
<div draggable > 可拖动的元素 </div>
复制代码
拖动事件
事件分类
元素可以进行拖动了,我们就可以通过元素的拖动事件进行拖动开始-结束的一些逻辑控制了,拖动事件主要分为两个类别,一类是拖动元素可以触发的:
dragstart:鼠标点中元素并且开始移动时触发
drag:拖拽过程中持续触发
dragend:拖拽结束松开鼠标时触发
另一类是,是当拖拽元素到某个目标元素时,目标元素会触发的:
dragenter:拖拽元素到目标上时触发
dragover:拖动元素在目标元素中,持续触发
dragleave:离开目标元素时触发
drop:拖放元素到了目标元素中松开鼠标时触发
拖动放置行为
在拖动事件中,我们会获取到拖动的事件对象 (e)
,在拖动对象中我们能获取到一个重要的属性 dataTransfer
,我们可以通过 dataTransfer
的 dropEffect
属性控制被拖动的元素的放置行为,其值的说明如下所示。
none:不能把元素拖放至此
move:移动到目标
copy:复制到目标
link:目标打开拖动元素(拖动元素必须是链接并有URL)
页面设计器的实现
下面我们根据以上的知识点来实现一下页面设计器组件拖动的最简demo。首先我们定义一下组件列表和画布区域
<template><div><!-- 左侧组件列表 --><div class="left"><divclass="left-item"v-for="item in list1":key="item.code"draggable>{{ item.name }}</div></div><!-- 画布区域 --><div class="targetContent" ref="targetContent"><divclass="item"v-for="item in list2":key="item.id":ref="item.id":style="{top: `${item.top - 16}px`,left: `${item.left - 85}px`,'z-index': `${item.zIndex}`}"><template v-if="item.code === 'MyInput'"><a-input></a-input></template></div></div></div>
</template>
复制代码
并将组件列表和画布中的页面分别通过list1,和list进行遍历渲染。
<script>
import _ from "lodash";
export default {data() {return {list1: [{code: "MyInput",name: "输入框",props: {}}],list2: [],};}
}
</script>
下面我们来分析一下如何实现将组件列表中的组件拖动到画布中,上文中我们讲到,拖动的元素以及目标元素可以设置一系列的事件,那么我们就可以在组件列表渲染时,为每个组件设置一下 dragstart
事件,在该事件中我们需要做如下处理:
设置拖动元素的放置行为为
移动
,即move
。组件在目标元素经过时,必须要阻止默认行为,否则不能触发
drop
。设置组件离开目标元素时放置行为为
不能拖放
,即none
。拖动元素在目标元素松手时添加元素到画布,即将组件元数据添加到
list2
中,元素所对应的元数据记录也了这个组件在画面中的坐标位置。
然后在dragend
事件中取听以上动作。
下面我们通过代码的方式来实现以上过程。首先在组件列表进行遍历时,添加组件的dragstart
和dragend
事件。
@dragstart="e => dragstart(e, item)"
@dragend="dragend"
复制代码
下面是这两个事件的实现。
dragstart(e, item) {this.dragItem = item;// 设置元素的放置行为——移动this.$refs.targetContent.addEventListener("dragenter", this.dragenter);// 在目标元素经过 必须要阻止默认行为 否则不能触发dropthis.$refs.targetContent.addEventListener("dragover", this.dragover);// 离开目标元素时设置元素的放置行为——不能拖放this.$refs.targetContent.addEventListener("dragleave", this.dragleave);// 拖动元素在目标元素松手时添加元素到画布this.$refs.targetContent.addEventListener("drop", this.drop);
},
dragend(e) {this.$refs.targetContent.removeEventListener("dragenter", this.dragenter);this.$refs.targetContent.removeEventListener("dragover", this.dragover);this.$refs.targetContent.removeEventListener("dragleave", this.dragleave);this.$refs.targetContent.removeEventListener("drop", this.drop);
},
dragenter(e) {e.dataTransfer.dropEffect = "move";
},
dragover(e) {e.preventDefault();
},
dragleave(e) {e.dataTransfer.dropEffect = "none";
},
drop(e) {const { code } = this.dragItem;this.list2.push({top: e.offsetY,left: e.offsetX,zIndex: 1,code: code,id: Date.parse(new Date())});this.dragItem = null;
}
拖拽牛逼,轻松实现一个自由拖拽的组件相关推荐
- 牛逼的python代码_牛逼啊!一个随时随地写Python代码的神器
现在学Python的人越来越多,很多小伙伴都非常有激情,利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...
- html列表拖拽排序插件,可对列表自由拖拽排序的jQuery插件
dragslot.js是一款可以对列表自由拖拽排序的jQuery插件.该插件主要的功能是实现了列表项可以在各个列表中相互拖拽. 对于像todo list, 分配任务列表都可以应用这个效果. 使用方法 ...
- python数据分析神器_牛逼啊!一个随时随地写Python代码的神器
作者: Leoxin 公众号:菜鸟学Python 现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练 ...
- 牛逼啊!一个可以随时随地写Python代码的神器
现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...
- java打字游戏代码_牛逼啊!一个随时随地写Python代码的神器
现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...
- 在手机上写python_牛逼啊!一个随时随地写Python代码的神器
2.运行非常方便 比如我们写一个简单的Python程序, 写一个推导列表. 这神器竟然还有代码提示功能,怕我们打字太累,直接会获取一些关键字,比如p打头的关键字,会给出一堆,这样可以省去打字的麻烦.而 ...
- 牛逼啊!一个随时随地写Python代码的神器
今天就推荐一个IOS手机上能写Python代码的App 叫Pythonista. 强大的Pythonista 1.功能强大 有一些小程序也是可以运行Python但是比较简单,这款神器是专业级别.里面有 ...
- 一个随时写python代码的神器_牛逼啊!一个随时随地写Python代码的神器
现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...
- Taro项目 实现一个在页面内自由拖拽的滑块,仿苹果手机的辅助按钮
效果:自由拖拽,松手会自动吸附到边上 组件代码: import { EventProps, ITouchEvent, View } from '@tarojs/components' import { ...
最新文章
- 12306 网站的非技术分析
- 助力中小企业级连云端,促进工业互联网平台蓬勃发展,全套解决方案。附:技术产品
- SQL Server 2012自动备份
- SpringMVC中拦截/和拦截/*的区别
- 2020年11月国产数据库排行: PingCAP融资破记录,PolarDB登云巅,达梦南大壮心雄
- KubeEdge 实践过程的记录
- 学校计算机社团都干些什么,计算机社团管理制度
- 夺命雷公狗---PDO NO:13 PDO的预处理查询4
- 父游标、子游标及共享游标
- python2中urllib.unquote乱码的原因与解决方法
- 根据android版本号,增加兼容性处理
- 擦窗机器人毕业设计_家用擦玻璃清洁机器人结构设计毕业设计说明方案.doc
- 跟着小马哥学系列之 Spring AOP(Pointcut 组件详解)
- Xneomai 简介
- 多图表数据分析PPT图表合集
- 两个学院少了计算机相关专业招生?985华中科技大学计算机考研
- [06][03][01] MySQL架构与SQL执行流程
- 20100919星期天最折腾的一天。
- 什么是json对象?
- 一个人,不管是富是穷,都可以富养自己