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 相关文章推荐
js setattribute批量设置css样式
Nov 26 Javascript
简单的jquery拖拽排序效果实现代码
Sep 20 Javascript
调试Node.JS的辅助工具(NodeWatcher)
Jan 04 Javascript
js全屏显示显示代码的三种方法
Nov 11 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
May 18 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
Nov 16 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
Sep 06 Javascript
JS获取html元素的标记名实现方法
Oct 08 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
Dec 26 Javascript
ECMAScript6变量的解构赋值实例详解
Sep 19 Javascript
JAVA面试题 static关键字详解
Jul 16 Javascript
解决Layui中templet中a的onclick参数传递的问题
Sep 20 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
ThinkPHP基于PHPExcel导入Excel文件的方法
2014/10/15 PHP
PHP连接操作access数据库实例
2015/03/30 PHP
jQuery ajax 路由和过滤器使用说明
2011/08/02 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
js data日期初始化的5种方法
2013/12/29 Javascript
JS实现当前页居中分页效果的方法
2015/06/18 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
基于bootstrap实现广告轮播带图片和文字效果
2016/07/22 Javascript
JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
2016/08/11 Javascript
Web打印解决方案之普通报表打印功能
2016/08/29 Javascript
jQuery EasyUI Draggable拖动组件
2017/03/01 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
5 种JavaScript编码规范
2018/01/30 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
jQuery实现文本显示一段时间后隐藏的方法分析
2019/06/20 jQuery
微信小程序图片右边加两行文字的代码
2020/04/23 Javascript
微信小程序返回上一级页面的实现代码
2020/06/19 Javascript
Vue清除定时器setInterval优化方案分享
2020/07/21 Javascript
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
python多重继承实例
2014/10/11 Python
详谈python read readline readlines的区别
2017/09/22 Python
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
2018/01/16 Python
django加载本地html的方法
2018/05/27 Python
python scatter散点图用循环分类法加图例
2019/03/19 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
Why we need EJB
2016/10/20 面试题
前台领班岗位职责
2013/12/04 职场文书
岗位工作说明书
2014/07/29 职场文书
学习党的群众路线实践活动思想汇报
2014/09/12 职场文书
2014司机年终工作总结
2014/12/05 职场文书
房产证明范本
2015/06/19 职场文书
《水上飞机》教学反思
2016/02/20 职场文书
评估“风险”创业计划的几大要点
2019/08/12 职场文书