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 相关文章推荐
二级域名或跨域共享Cookies的实现方法
Aug 07 Javascript
基于js disabled=&quot;false&quot;不起作用的解决办法
Jun 26 Javascript
jquery解析xml字符串简单示例
Apr 11 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
Oct 08 Javascript
Javascript中this关键字的一些小知识
Mar 15 Javascript
AngularJS实现的JSONP跨域访问数据传输功能详解
Jul 20 Javascript
react-native-tab-navigator组件的基本使用示例代码
Sep 07 Javascript
react redux入门示例
Apr 19 Javascript
使用Nuxt.js改造已有项目的方法
Aug 07 Javascript
对layui中表单元素的使用详解
Aug 15 Javascript
详解基于node.js的脚手架工具开发经历
Jan 28 Javascript
WebWorker 封装 JavaScript 沙箱详情
Nov 02 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连接MongoDB示例代码
2012/09/06 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
2013/07/05 PHP
CI框架自动加载session出现报错的解决办法
2014/06/17 PHP
PHP实现根据设备类型自动跳转相应页面的方法
2014/07/24 PHP
php检测文本的编码
2015/07/26 PHP
Laravel下生成验证码的类
2017/11/15 PHP
jQuery 使用手册(六)
2009/09/23 Javascript
通过百度地图获取公交线路的站点坐标的js代码
2012/05/11 Javascript
Javascript计算两个marker之间的距离(Google Map V3)
2013/04/26 Javascript
js下拉菜单语言选项简单实现
2013/09/23 Javascript
浅析document.ready和window.onload的区别讲解
2013/12/18 Javascript
Jquery中扩展方法extend使用技巧
2014/08/24 Javascript
jQuery实现鼠标滚轮动态改变样式或效果
2015/01/05 Javascript
浅谈angular.js中实现双向绑定的方法$watch $digest $apply
2015/10/14 Javascript
基于JS实现PHP的sprintf函数实例
2015/11/14 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
JS基础随笔(菜鸟必看篇)
2016/07/13 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
微信小程序rich-text富文本用法实例分析
2019/05/20 Javascript
浅谈layui 数据表格前后台传值的问题
2019/09/12 Javascript
小程序调用微信支付的方法
2019/09/26 Javascript
vue基于better-scroll仿京东分类列表
2020/06/30 Javascript
从零学python系列之从文件读取和保存数据
2014/05/23 Python
5种Python单例模式的实现方式
2016/01/14 Python
详解Appium+Python之生成html测试报告
2019/01/04 Python
python绘制BA无标度网络示例代码
2019/11/21 Python
Python接口测试结果集实现封装比较
2020/05/01 Python
python中id函数运行方式
2020/07/03 Python
HTML5 标准将把互联网视频扔回到黑暗时代
2010/02/10 HTML / CSS
使用 HTML5 Canvas 制作水波纹效果点击图片就会触发
2014/09/15 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
德国大型箱包和皮具商店:Koffer
2019/10/01 全球购物
公司总经理工作职责管理办法
2014/02/28 职场文书
2014年乡镇工会工作总结
2014/12/02 职场文书
Java如何实现通过键盘输入一个数组
2022/02/15 Java/Android
Python如何使用循环结构和分支结构
2022/04/13 Python