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 相关文章推荐
基于jquery的监控数据是否发生改变
Apr 11 Javascript
js实现类似菜单风格的TAB选项卡效果代码
Aug 28 Javascript
JS中frameset框架弹出层实例代码
Apr 01 Javascript
js实时获取窗口大小变化的实例代码
Nov 18 Javascript
浅析JavaScript中作用域和作用域链
Dec 06 Javascript
js实现省份下拉菜单效果
Feb 15 Javascript
微信小程序 MD5的方法详解及实例代码
Mar 10 Javascript
利用js给datalist或select动态添加option选项的方法
Jan 25 Javascript
Node.js 使用jade模板引擎的示例
May 11 Javascript
vue配置多页面的实现方法
May 22 Javascript
详解bootstrap-fileinput文件上传控件的亲身实践
Mar 21 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
Aug 22 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实现下载文件的两种方法
2013/07/05 PHP
PHP判断浏览器、判断语言代码分享
2015/03/05 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
WordPress中&quot;无法将上传的文件移动至&quot;错误的解决方法
2015/07/01 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
ThinkPHP实现附件上传功能
2017/04/27 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
2012/12/15 Javascript
js实现一个省市区三级联动选择框代码分享
2013/03/06 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
node.js中的fs.appendFileSync方法使用说明
2014/12/17 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形网络(1)
2015/11/30 Javascript
Angularjs 滚动加载更多数据
2016/03/17 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
json定义及jquery操作json的方法
2016/10/03 Javascript
Bootstrap按钮功能之查询按钮和重置按钮
2016/10/26 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
2016/10/31 Javascript
JavaScript运动框架 多物体任意值运动(三)
2017/05/17 Javascript
vue2导航根据路由传值,而改变导航内容的实例
2017/11/10 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
Vue项目中使用jquery的简单方法
2019/05/16 jQuery
js实现鼠标切换图片(无定时器)
2021/01/27 Javascript
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
深入浅析python继承问题
2016/05/29 Python
对python的文件内注释 help注释方法
2018/05/23 Python
用python打印1~20的整数实例讲解
2019/07/01 Python
Python爬虫之urllib基础用法教程
2019/10/12 Python
phonegap常用事件总结(必看篇)
2017/03/31 HTML / CSS
办公室前台岗位职责范本
2013/12/10 职场文书
司法建议书范文
2014/05/13 职场文书
会计继续教育培训心得体会
2016/01/19 职场文书
2016年国庆节67周年活动总结
2016/04/01 职场文书
​(迎国庆)作文之我爱我的祖国
2019/09/19 职场文书
Redis基本数据类型哈希Hash常用操作命令
2022/06/01 Redis
MySQL数据库表约束讲解
2022/06/21 MySQL