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 相关文章推荐
javascript基于jQuery的表格悬停变色/恢复,表格点击变色/恢复,点击行选Checkbox
Aug 05 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
Mar 01 Javascript
JavaScript将当前时间转换成UTC标准时间的方法
Apr 06 Javascript
利用jQuery中的ajax分页实现代码
Feb 25 Javascript
简单实现js页面切换功能
Jan 10 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
Aug 05 Javascript
详解AngularJS如何实现跨域请求
Aug 22 Javascript
值得分享的JavaScript实现图片轮播组件
Nov 21 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
Dec 23 Javascript
JS查找数组中重复元素的方法详解
Jun 14 Javascript
jQuery实现的简单日历组件定义与用法示例
Dec 24 jQuery
在layer弹层layer.prompt中,修改placeholder的实现方法
Sep 27 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
关于我转生变成史莱姆这档事:第二季PV上线,萌王2021年回归
2020/05/06 日漫
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
2014/10/23 PHP
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
PHP实现linux命令tail -f
2016/02/22 PHP
学习YUI.Ext基础第一天
2007/03/10 Javascript
Javascript 跨域访问解决方案
2009/02/14 Javascript
javascript 日期时间函数(经典+完善+实用)
2009/05/27 Javascript
学习ExtJS(二) Button常用方法
2009/10/07 Javascript
自己实现string的substring方法 人民币小写转大写,数字反转,正则优化
2012/09/02 Javascript
常用的Javascript数据验证插件
2015/08/04 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
使用百度地图实现地图网格的示例
2018/02/06 Javascript
微信小程序之自定义组件的实现代码(附源码)
2018/08/02 Javascript
layui的table中显示图片方法
2018/08/17 Javascript
详解vue中的父子传值双向绑定及数据更新问题
2019/06/13 Javascript
JavaScript基于面向对象实现的无缝滚动轮播示例
2020/01/17 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
使用vue引入maptalks地图及聚合效果的实现
2020/08/10 Javascript
[38:44]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第二局
2016/02/25 DOTA
利用Python爬取可用的代理IP
2016/08/18 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
python基于property()函数定义属性
2020/01/22 Python
Django 5种类型Session使用方法解析
2020/04/29 Python
中东奢侈品购物网站:Ounass
2020/09/02 全球购物
.NET现在共支持多少种语言
2014/02/26 面试题
MVC的各个部分都有那些技术来实现?如何实现?
2016/04/21 面试题
医学院护理专业应届生求职信
2013/11/12 职场文书
母亲七十大寿答谢词
2014/01/18 职场文书
仓库管理制度
2014/01/21 职场文书
厨师长岗位职责
2014/03/02 职场文书
财务会计专业求职信
2014/06/09 职场文书
护士工作失误检讨书
2014/09/14 职场文书
德能勤绩工作总结
2015/08/11 职场文书
Linux磁盘管理方法介绍
2022/06/01 Servers