HTML5之拖放Drag &Drop

作者:月光光整理 2016年09月03日 12:32helloweba.com 标签:HTML5 

拖放(Drag &Drop)是一种常见的特性,即抓取对象以后拖到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。过去,我们用监听鼠标的Mousedown、Mouseove、Mouseup等事件来不停地获取鼠标的坐标来修改元素的位置,而现在html5原生的Drag &Drop事件(DnD),方便了许多,而且性能也有了提高。

Internet Explorer 9+、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。

如何使对象能够被拖动

为了使元素可拖动,把 draggable 属性设置为 true :

<div draggable="true">可拖动的div</div>

注意:在大多数浏览器中,a元素和img元素默认就是可以拖放的,但是为了保险起见,最好还是加上draggable属性。

拖动事件

dragstart:网页元素开始拖动时触发。

drag:被拖动的元素在拖动过程中持续触发。

dragenter:被拖动的元素进入目标元素时触发,应在目标元素监听该事件。

dragleave:被拖动的元素离开目标元素时触发,应在目标元素监听该事件。

dragover:被拖动元素停留在目标元素之中时持续触发,应在目标元素监听该事件。

drap:被拖动元素或从文件系统选中的文件,拖放落下时触发。

dragend:网页元素拖动结束时触发。

注意:以上这些事件都可以指定回调函数。

dataTransfer对象

拖动过程中,回调函数接受的事件参数,有一个dataTransfer属性。它指向一个对象,包含了与拖动相关的各种信息。

draggableElement.addEventListener('dragstart', function(event) {       
	event.dataTransfer.setData('text', 'Helloweba');
});

上面代码在拖动开始时,在dataTransfer对象上储存一条文本信息,内容为“Helloweba”。当拖放结束时,可以用getData方法取出这条信息。

dataTransfer对象的属性:

effectAllowed:指定所允许的操作,可能的值为copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默认值,等同于all,即允许一切操作)。

files:包含一个FileList对象,表示拖放所涉及的文件,主要用于处理从文件系统拖入浏览器的文件。

types:储存在DataTransfer对象的数据的类型。

dataTransfer对象的方法:

setData(format, data):在dataTransfer对象上储存数据。第一个参数format用来指定储存的数据类型,比如text、url、text/html等。

getData(format):从dataTransfer对象取出数据。

clearData(format):清除dataTransfer对象所储存的数据。如果指定了format参数,则只清除该格式的数据,否则清除所有数据。

setDragImage(imgElement, x, y):指定拖动过程中显示的图像。默认情况下,许多浏览器显示一个被拖动元素的半透明版本。参数imgElement必须是一个图像元素,而不是指向图像的路径,参数x和y表示图像相对于鼠标的位置。

dataTransfer对象允许在其上存储数据,这使得在被拖动元素与目标元素之间传送信息成为可能。

实例代码

在实例中,我们设置从一个盒子中将元素拖放到另一个盒子元素中。

HTML结构如下:

<ul id="drags">
	<li draggable="true">A</li>
	<li draggable="true">B</li>
	<li draggable="true">C</li>
</ul>
<ul id="drops"></ul>

#drags是被拖动的对象盒子,#drops是目标区域盒子。

javascript代码:

<script type="text/javascript">
//获取目标元素
var target = document.querySelector('#drops');
//获取需要拖放的元素
var dragElements = document.querySelectorAll('#drags li');
//临时记录被拖放的元素
var elementDragged = null;
//循环监听被拖放元素的开始拖放和结束拖放事件
for (var i = 0; i < dragElements.length; i++) {
	//开始拖放事件监听
	dragElements[i].addEventListener('dragstart', function(e) {
		//设置当前拖放元素的数据参数
		e.dataTransfer.setData('text', this.innerHTML);
		//保存当前拖放对象
		elementDragged = this;
	});
	//结束拖放事件监听
	dragElements[i].addEventListener('dragend', function(e) {
		//注销当前拖放对象
		elementDragged = null;
	});
}
//目标元素监听被拖放元素进入事件
target.addEventListener('dragover', function(e) {
	//阻止浏览器默认行为
	e.preventDefault();
	//设置鼠标样式
	e.dataTransfer.dropEffect = 'move';
	return false;
});
//目标元素监听当被拖放元素落下时刻事件
target.addEventListener('drop', function(e) {
	//阻止默认行为
	e.preventDefault();
	//阻止默认行为
	e.stopPropagation();
	//获取当前被拖放元素的存放数据参数
	var text = e.dataTransfer.getData('text');
	//建立元素
	var node=document.createElement("li");
	var textnode=document.createTextNode(text);
	node.appendChild(textnode);
	this.appendChild(node);


	//删除被拖放元素
	document.querySelector('#drags').removeChild(elementDragged);    
	return false;
});
</script>

注意我们要调用 preventDefault() 来避免浏览器对数据的默认处理(drop 事件的默认行为是以链接形式打开),此外,通过 dataTransfer.getData("Text") 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据。

最后结合File Api,可以获得本地拖放文件。FileReader专门用于读取文件,根据 W3C 的定义,FileReader 接口“提供一些读取文件的方法与一个包含读取结果的事件模型”。有关文件拖动的实例可以参考本站文章:HTML5应用之文件拖拽上传


3条评论

  • 有个bug,拖拽到右侧的元素,还可以再拖拽复制

  • 这篇文章我喜欢,感谢分享

  • 谢谢分享