vue 中基于html5 drag drap的拖放效果案例分析


Posted in Javascript onNovember 01, 2018

 事情是这样的,右边有各种控件,可以拖动到右边自由区,在自由区内可以随意拖动。

vue 中基于html5 drag drap的拖放效果案例分析

案例一:

开始的我,so easy! 通过绑定元素的mousedown 事件,监听鼠标的mousemove,和mouseup 事件,于是我轻松实现了同一区域内元素可以拖着跑,上代码!

move (e) {
  let odiv = e.target // 获取目标元素
  // 算出鼠标相对元素的位置
  let disX = e.clientX - odiv.offsetLeft
  let disY = e.clientY - odiv.offsetTop
  document.onmousemove = e => {
  // 鼠标按下并移动的事件
  // 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
  let left = e.clientX - disX
  let top = e.clientY - disY
  // 移动当前元素
  odiv.style.left = left + 'px'
  odiv.style.top = top + 'px'
  }
  document.onmouseup = e => {
  document.onmousemove = null
  document.onmouseup = null
  }
 }

注意一点,被拖拽对象区域要设置position:relative, 否则的元素会自己抖动。

以上代码并不能满足需要,要左右布局,左边的拖到右边,在右边区域随便拖动。

案例二:

好吧,首先我来布个局,左右布局,给元素绑定事件,上代码!

<template>
 <div style='position: relative;'>
 <el-container>
  <el-aside width="300px">
  <ul>
   <li class='liStyle' v-for="item in tags" :key='item.id'><img src="../assets/timg.png" class='msg' alt="" @dragstart="dragstart" draggable="true" @drag='draging' @dragend="dragend"></li>
  </ul>
  </el-aside>
  <!-- 自由移动区域 -->
  <el-main>
  <div @drop="drop" @dragover.prevent style='height:600px;width:800px;'>
  </div>
  <!-- <svg id="svgDrag" width="1200" height="1000"></svg> -->
  </el-main>
 </el-container>
 </div>
</template>

事件绑定方法:

dragstart (ev) {
  console.log('dragstart拖拽开始事件,绑定于被拖拽元素上', event)
  ev.dataTransfer.setData('Text', ev.target.id)
  this.offsetX = ev.offsetX
  this.offsetY = ev.offsetY
  console.log(this.offsetX + '-' + this.offsetY)
 },
 draging (e) {
  // console.log('拖动中')
  var x = e.clientX
  var y = e.clientY
  // console.log('shubiao client')
  if (x > 300) {
  console.log(this.tags)
  // drag事件最后一刻,无法读取鼠标的坐标,pageX和pageY都变为0
  if (x === 0 && y === 0) {
   return // 不处理拖动最后一刻X和Y都为0的情形
  }
  x -= this.offsetX
  y -= this.offsetY
  // console.log('e left')
  // console.log(x + '-' + y)
  /* 它的父级第一个存在定位的元素,如果有margin减去margin值 */
  e.target.style.left = x - 5 + 'px'
  e.target.style.top = y - 60 + 'px'
  }
 },
 drop (ev) {
  console.log('drop拖放事件,绑定可拖放区域', event)
  this.text = ev.dataTransfer.getData('Text')
  console.log(this.text)
  let target = document.getElementById(this.text)
  ev.target.appendChild(target)
  ev.preventDefault()
 },
 dragend (event) {
  event.dataTransfer.clearData()
 }

如果不出意外的话,以上代码已经成功实现了元素从左边拖到右边。但是,右边元素被拖走了,右边就没有了,然后我尝试了各种,拖动开始时clone 元素,drap时clone元素等等,都不太完美。此时的我,崩溃……

终于,也不知道哪来的灵感,这个困扰我两秒的难题突然就被我成功攻克了。好了,我要开始吹牛了……

  案例三:

       我的思路是这样的(不想看?直接看代码好了,反正是给我自己看的):左边列表元素可拖动(draggable='true'),绑定dragstart(开始事件),不要给它绑定draging(拖动事件),这样左边列表元素有拖动属性,但是位置不会改变。当右侧拖动区域

第一次触发了drop 操作后,新生成一个对象,这个对象既有拖动(draggable='true')属性,也绑定dragstart(开始事件),拖动事件(drag),这样新元素会在右侧随意拖动。那么怎么新生成一个元素呢?自然不是appendChild 之类的,利用Vue 双向绑定的特性,

页面上循环数组元素,生成元素即往数组中push 元素即可。每次拖动元素都会触发drop 事件,并不是每次都要生成一个新元素,要知道是从左边列表拖到右侧第一次drop 的时候生成新元素。怎么知道呢?这就是两个dragstart的妙处

<t<template>
 <div style='position: relative;'>
 <el-container>
  <el-aside width="300px">
  <ul>
   <li class='liStyle' v-for="item in tags" :key='item.id'>
   <img src="../assets/timg.png" class='msg' alt="" @dragstart="dragstart" draggable="true" :id='item.id' @dragend="imgEnd">
   </li>
  </ul>
  </el-aside>
  <el-main>
  <div @drop.prevent="drop" @dragover.prevent style='height:1000px;width:1800px;'>
   <img src="../assets/timg.png" class='msg' :style="{left:item.x+'px',top:item.y+'px'}" alt="" v-for="(item, $index) in InfoList" :key='$index' @dragstart="imgStart" draggable="true" @drag='draging($event,item)' @dragend="imgEnd">
  </div>
  </el-main>
 </el-container>
 </div>
</template> 

methods: {
 dragstart (ev) {
 let info = { id: ev.target.id, isDrop: true }
 ev.dataTransfer.setData('Text', JSON.stringify(info))
 this.offsetX = ev.offsetX
 this.offsetY = ev.offsetY
 },
 drop (e) {
 let info = JSON.parse(e.dataTransfer.getData('Text'))
 /* 判断是否是第一次进入拖拽区域,如果是第一次需要新生成对象,否则不需要 */
 if (info.isDrop) {
  var x = e.clientX
  var y = e.clientY
  x -= this.offsetX
  y -= this.offsetY
  info.x = x - 5
  info.y = y - 60
  info.id = info.id + Date.parse(new Date())
  this.InfoList.push(info)
 }
 },
 imgStart (e) {
 let info = { isDrop: false }
 e.dataTransfer.setData('Text', JSON.stringify(info))
 this.imgOffsetX = e.offsetX
 this.imgOffsetY = e.offsetY
 },
 draging (e, item) {
 item.x = e.clientX - this.imgOffsetX - 5
 item.y = e.clientY - this.imgOffsetY - 60
 },
 imgEnd (event) {
 console.log('done')
 console.log(event)
 event.dataTransfer.clearData()
 }
}

注意:拖动元素设置position:absolute属性

总结

以上所述是小编给大家介绍的vue 中基于html5 drag drap的拖放效果案例分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
控制台报错object is not a function的解决方法
Aug 24 Javascript
php常见的页面跳转方法汇总
Apr 15 Javascript
jQuery实现鼠标跟随提示层效果代码(可显示文本,Div,Table,Html等)
Apr 18 Javascript
jquery.form.js框架实现文件上传功能案例解析(springmvc)
May 26 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
May 02 Javascript
js 两个日期比较相差多少天的实例
Oct 19 Javascript
js生成word中图片处理方法
Jan 06 Javascript
jQuery实现带3D切割效果的轮播图功能示例【附源码下载】
Apr 04 jQuery
vue2 中二级路由高亮问题及配置方法
Jun 10 Javascript
原生javascript自定义input[type=radio]效果示例
Aug 27 Javascript
微信小程序登录时如何获取input框中的内容
Dec 04 Javascript
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
Aug 06 Javascript
Vue列表渲染的示例代码
Nov 01 #Javascript
socket io与vue-cli的结合使用的示例代码
Nov 01 #Javascript
Vue表单输入绑定的示例代码
Nov 01 #Javascript
浅谈Angular 观察者模式理解
Nov 01 #Javascript
详解vuex状态管理模式
Nov 01 #Javascript
详解angularjs跨页面传参遇到的一些问题
Nov 01 #Javascript
Vue.js 事件修饰符的使用教程
Nov 01 #Javascript
You might like
php设计模式 Observer(观察者模式)
2011/06/26 PHP
新手学习PHP的一些基础知识分享
2011/07/27 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
laravel-admin select框默认选中的方法
2019/10/03 PHP
论坛里点击别人帖子下面的回复,回复标题变成“回复 24# 的帖子”
2009/06/14 Javascript
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
javascript遍历控件实例详细解析
2014/01/10 Javascript
Jquery遍历checkbox获取选中项value值的方法
2014/02/13 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
2016/11/25 Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
2017/02/15 Javascript
使用Vue开发一个实时性时间转换指令
2018/01/17 Javascript
JS跨浏览器解析XML应用过程详解
2020/10/16 Javascript
三剑客:offset、client和scroll还傻傻分不清?
2020/12/04 Javascript
Python闭包实现计数器的方法
2015/05/05 Python
Python 编码Basic Auth使用方法简单实例
2017/05/25 Python
python的Tqdm模块的使用
2018/01/10 Python
Django使用详解:ORM 的反向查找(related_name)
2018/05/30 Python
Tensorflow使用tfrecord输入数据格式
2018/06/19 Python
Python BS4库的安装与使用详解
2018/08/08 Python
一行代码让 Python 的运行速度提高100倍
2018/10/08 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
pyqt5 lineEdit设置密码隐藏,删除lineEdit已输入的内容等属性方法
2019/06/24 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
漫威玩具服装及周边商品官方购物网站:Marvel Shop
2019/05/11 全球购物
日本亚马逊官方网站:Amazon.co.jp
2020/04/14 全球购物
Java中的类包括什么内容?设计时要注意哪些方面
2012/05/23 面试题
中医专业应届生求职信
2013/11/17 职场文书
危货运输企业安全生产责任书
2014/07/28 职场文书
高中运动会广播稿
2014/09/16 职场文书
2015年试用期自我评价范文
2015/03/10 职场文书
2015年基层党建工作总结
2015/05/14 职场文书
婚礼双方父亲致辞
2015/07/27 职场文书
sql通过日期判断年龄函数的示例代码
2021/07/16 SQL Server
海弦WR-800F
2022/04/05 无线电