Vue结合Html5中drag和drop实现拖拽与放置

目标

推拽和放置是html5常用事件,利用Vue对事件的改造,实现一个从左边区域推拽元素,并放置到右边区域的功能

效果

Vue结合Html5中drag和drop实现拖拽与放置_第1张图片

概念

  • 【源对象】拖拽的事件:
Html5 Vue 含义 备注
ondragstart 用户开始拖动元素时触发
ondrag 元素正在拖动时触发
ondragend 用户完成元素拖动后触发
  • 【目标区域】放置的事件:
Html5 Vue 含义 备注
ondragenter 用户开始拖当被鼠标拖动的对象进入其容器范围内时触发此事件元素时触发
ondragover 元素当某被拖动的对象在另一对象容器范围内拖动时触发此事件拖动时触发
ondragleave 用户完成元素当被鼠标拖动的对象离开其容器范围内时触发此事件动后触发
ondrop 在一个拖动过程中,释放鼠标键时触发此事件
  • 必须给拖放区元素添加 dragover.prevent,才能使 drop 事件正确执行

参考:Html5推拽与放置

源码

<template>
	<div class="container">
		<img id="img-text" src="@/assets/text.png" style="display: none;"/>
		<img id="img-button" src="@/assets/button.png" style="display: none;"/>
		<div class="left-warp">
			<ul>
				<li id="text" draggable="true" @dragstart="dragstart($event)">元素A</li>
				<li id="button" draggable="true" @dragstart="dragstart($event)">元素B</li>
			</ul>
		</div>
		<div :class="dragLines?'lines':''" id="item-room" class="right-warp" @dragenter="dragenter($event)" @dragleave="dragleave($event)" @drop="drop($event)" @dragover.prevent>
			<ul>
				<li v-for="(item,index) in arrs">{{item.text}}</li>
			</ul>
		</div>
	</div>
</template>
<script type="text/javascript">
	let elemetnNode=""//最先进入的地方	
	export default{
		data(){
			return{
				arrs:[],
				dragLines:false
			}
		},
		methods:{
			/**
			 * 拖动开始前
			 * e $event 
			 */
			dragstart(e){
				this.dragLines=true
				e.dataTransfer.setData('id', e.target.id);
				
				let imageText = document.getElementById('img-text').cloneNode();
				let imageButton = document.getElementById('img-button').cloneNode();
				if(e.target.id=='text'){
					e.dataTransfer.setDragImage(imageText,150,150);
				}
				if(e.target.id=='button'){
					e.dataTransfer.setDragImage(imageButton,150,150);
				}
			},
			/**
			 * 放置目标
			 * @param {Object} e
			 */
			drop(e){
				// console.log('drop::',e);
				e.preventDefault()//阻止浏览器读取文件
				let id = e.dataTransfer.getData('id');
				if(id==='text'){
					this.arrs.push({text:'元素A'})
				}
				if(id==='button'){
					this.arrs.push({text:'元素B'})
				}
				this.dragLines=false
			},
			/**
			 * 进入目标区域时[待用]
			 * 默认区域内子目标都会出现进入,使用elemetnNode标记第一次进入的区域
			 * @param {Object} e
			 */
			dragenter(e){
				elemetnNode=e.target;
				console.log('drapenter')
			},
			/**
			 * 离开目标区域时[待用]
			 * 默认区域内子目标都会出现进入,使用elemetnNode标记第一次进入的区域
			 * @param {Object} e
			 */
			dragleave(e){
				if(elemetnNode===e.target){
					console.log('drapleave')
				}
			},
			
		}
	}
</script>
<style type="text/css" lang="scss" scoped>
	.container{
		height: 100%;
		display: flex;
		position: relative;
		.left-warp{
			height: 100%;
			width: 200px;
			background-color: #f9fcff;
			padding: 20px;
			ul li{
				background-color: #e1edff;
				margin-bottom: 10px;
				height: 30px;
				line-height: 30px;
				text-align: center;
				cursor: move;
			}
		}
		.right-warp{
			width: 100%;
			background-color: #fff;
			padding: 20px;
			border: 1px dashed #fff;
			ul li{
				background-color: #e1edff;
				margin-bottom: 10px;
				height: 30px;
				line-height: 30px;
				text-align: center;
			}
		}
		.lines{
			border-color: #DD4A68;
		}
	}
</style>

解释

实现拖拽且放置,核心是三个事件:draggable="true",@dragstart,@drop

  • draggable="true",@dragstart – 源对象上使用,添加draggable="true",属性后,元素就可以被推拽了,默认是拖出一个半透明的源对象拷贝,但是不能放置
  • 在目标区域div使用@drop
  • @dragstart – 源对象上使用,使用dataTransfer设置值,在放置时可以取出
  • @drop – 目标区域div上使用,使用dataTransfer获取值,根据情况v-for新元素
  • e.dataTransfer.setData('id', e.target.id) – 参考:dataTransfer对象
  • e.dataTransfer.setDragImage(imageText,150,150) – 设置推拽中跟随鼠标的图像,默认是源对象半透明图像,如果自定义跟随图像,必须是页面上存在的图片

Vue Drag and Drop
HTML5–拖放事件与dataTransfer对象

项目源码

你可能感兴趣的:(HTML5,vue.js,html5,javascript)