如何使元素支持拖动

实现组件的自由拖动的核心就是 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 事件,在该事件中我们需要做如下处理:

  1. 设置拖动元素的放置行为为移动,即move

  2. 组件在目标元素经过时,必须要阻止默认行为,否则不能触发drop

  3. 设置组件离开目标元素时放置行为为不能拖放,即none

  4. 拖动元素在目标元素松手时添加元素到画布,即将组件元数据添加到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;
}

拖拽牛逼,轻松实现一个自由拖拽的组件相关推荐

  1. 牛逼的python代码_牛逼啊!一个随时随地写Python代码的神器

    现在学Python的人越来越多,很多小伙伴都非常有激情,利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...

  2. html列表拖拽排序插件,可对列表自由拖拽排序的jQuery插件

    dragslot.js是一款可以对列表自由拖拽排序的jQuery插件.该插件主要的功能是实现了列表项可以在各个列表中相互拖拽. 对于像todo list, 分配任务列表都可以应用这个效果. 使用方法 ...

  3. python数据分析神器_牛逼啊!一个随时随地写Python代码的神器

    作者: Leoxin 公众号:菜鸟学Python 现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练 ...

  4. 牛逼啊!一个可以随时随地写Python代码的神器

    现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...

  5. java打字游戏代码_牛逼啊!一个随时随地写Python代码的神器

    现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...

  6. 在手机上写python_牛逼啊!一个随时随地写Python代码的神器

    2.运行非常方便 比如我们写一个简单的Python程序, 写一个推导列表. 这神器竟然还有代码提示功能,怕我们打字太累,直接会获取一些关键字,比如p打头的关键字,会给出一堆,这样可以省去打字的麻烦.而 ...

  7. 牛逼啊!一个随时随地写Python代码的神器

    今天就推荐一个IOS手机上能写Python代码的App 叫Pythonista. 强大的Pythonista 1.功能强大 有一些小程序也是可以运行Python但是比较简单,这款神器是专业级别.里面有 ...

  8. 一个随时写python代码的神器_牛逼啊!一个随时随地写Python代码的神器

    现在学Python的人越来越多,很多小伙伴都非常有激情.利用碎片时间随时随地学习Python, 大家知道Python是一门编程语言,但是学语言光看不练是没有用的.最好能编程并运行,有没有什么好的神器可 ...

  9. Taro项目 实现一个在页面内自由拖拽的滑块,仿苹果手机的辅助按钮

    效果:自由拖拽,松手会自动吸附到边上 组件代码: import { EventProps, ITouchEvent, View } from '@tarojs/components' import { ...

最新文章

  1. 12306 网站的非技术分析
  2. 助力中小企业级连云端,促进工业互联网平台蓬勃发展,全套解决方案。附:技术产品
  3. SQL Server 2012自动备份
  4. SpringMVC中拦截/和拦截/*的区别
  5. 2020年11月国产数据库排行: PingCAP融资破记录,PolarDB登云巅,达梦南大壮心雄
  6. KubeEdge 实践过程的记录
  7. 学校计算机社团都干些什么,计算机社团管理制度
  8. 夺命雷公狗---PDO NO:13 PDO的预处理查询4
  9. 父游标、子游标及共享游标
  10. python2中urllib.unquote乱码的原因与解决方法
  11. 根据android版本号,增加兼容性处理
  12. 擦窗机器人毕业设计_家用擦玻璃清洁机器人结构设计毕业设计说明方案.doc
  13. 跟着小马哥学系列之 Spring AOP(Pointcut 组件详解)
  14. Xneomai 简介
  15. 多图表数据分析PPT图表合集
  16. 两个学院少了计算机相关专业招生?985华中科技大学计算机考研
  17. [06][03][01] MySQL架构与SQL执行流程
  18. 20100919星期天最折腾的一天。
  19. 什么是json对象?
  20. 一个人,不管是富是穷,都可以富养自己

热门文章

  1. 特种部队小组2+蒲公英联机平台联机教程
  2. 团队管理的四大挑战——裁人篇
  3. 视频压缩【亲测可用】
  4. 自动化运维初级村-Netmiko-巡检-2
  5. PyEcharts 基本图表之雷达图
  6. iphone开发中的手势操作:Multiple Taps
  7. win10上网显示dns服务器未响应,win10无法上网DNS服务器未响应的解决方法
  8. BIgDecimal的用法,及与各类数据类型的转换
  9. 遭遇cursor:pin x等待事件定位阻塞会话诊断过程
  10. 怎么把图片转换成Tikz图片