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

目标

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

效果

效果图

概念

  • 【源对象】拖拽的事件:
Html5Vue含义备注
ondragstart用户开始拖动元素时触发
ondrag元素正在拖动时触发
ondragend用户完成元素拖动后触发
  • 【目标区域】放置的事件:
Html5Vue含义备注
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对象

项目源码

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值