拖拽(Drag/Drop)是个非常普遍的功能。在使用电脑的过程中,拖放一个东西是相当常见。很多javascript都类似实现了相关的功能,例如,jQueryUI的draganddrop组件。在HTML5中,拖拽(draganddrop)成为了标准操作,任何元素都可以进行拖放。
拖拽涉及的知识点
在拖放的过程中会触发以下事件:
在拖动目标上触发事件 (源元素):
ondragstart - 用户开始拖动元素时触发
ondrag - 元素正在拖动时触发(鼠标可能在移动也可能未移动)
ondragend - 用户完成元素拖动后触发
释放目标时触发的事件:
ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
浏览器支持
Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 支持拖动。
注意:Safari 5.1.2不支持拖动;在拖动元素时,每隔 350 毫秒会触发 ondragover 事件
如何在拖动的源对象事件和目标对象事件间传递数据
1. HTML5为所有的拖动相关事件提供了一个新的属性dataTransfer :
e.dataTransfer { } //数据传递对象
功能:用于在源对象和目标对象的事件间传递数据
2. 源对象上的事件处理中保存数据:
e.dataTransfer.setData( k, v ); //k-v必须都是string类型
3. 目标对象上的事件处理中读取数据:
var v = e.dataTransfer.getData( k );
虽然所有元素都支持放置目标事件,但这些元素默认是不允许放置的,需要重写事件的默认行为
e.stopPropagation();
e.preventDefault();
另外,还有一个不得不考虑的问题是,拖拽的对象可能是文件,图片,文字。
div
// html
<div class="container">
<div class="page-header">
<h1>Drag&Drop</h1></div>
<div class="jumbotron">
<p>选择上传的文件</p>
<img src="toy.png" alt="">
</div>
<ul id="result" class="list-group"></ul>
<div id="target">
Drag something into here
</div>
</div>
js部分
// js
<script>
var source = document.querySelector('.jumbotron');//拖拽的元素
//拖动什么 - dragstart 和 setData()
source.addEventListener('dragstart', function(e) {
// e.dataTransfer.setData('type', e.target);
// e.dataTransfer.effectAllowed = 'copy';
return true;
});
var target = document.querySelector('#target');//拖到的目标位置
//dragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
target.addEventListener('dragenter', function(e) {
e.stopPropagation(); // 一定要组织浏览器的默认行为
e.preventDefault();
this.classList.add('actived');//添加actived类名
});
//dragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
target.addEventListener('dragleave', function(e) {
e.stopPropagation(); // 一定要组织浏览器的默认行为
e.preventDefault();
this.classList.remove('actived');//移除actived类名
});
//dragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
target.addEventListener('dragover', function(e) {
// 一定要组织浏览器的默认行为
e.stopPropagation();
e.preventDefault();
});
//进行放置 - drop
//当放置被拖数据时,会发生 drop 事件。
target.addEventListener('drop', function(e) {
e.stopPropagation();// 一定要组织浏览器的默认行为
e.preventDefault();
this.classList.remove('actived');//移除actived类名
target.innerHTML = '';
if (e.dataTransfer.files.length) {//如果拖拽的是file
for (var i = 0; i < e.dataTransfer.files.length; i++) {
var file = e.dataTransfer.files.item(i);
var li = document.createElement('li');
li.className = 'list-group-item';
var h4 = document.createElement('h4');
h4.className = 'list-group-item-heading';
h4.appendChild(document.createTextNode(file.name));
var p = document.createElement('p');
p.className = 'list-group-item-text';
p.appendChild(document.createTextNode(file.type + ' ' + file.lastModifiedDate.toLocaleDateString() + ' ' + (file.size / 1024 / 1024).toFixed(2) + 'MB'));
li.appendChild(h4);
li.appendChild(p);
document.querySelector('#result').appendChild(li);
}
target.innerHTML = 'Drag something into here';
return false;
}
var uri = e.dataTransfer.getData('text/uri-list');
var text = e.dataTransfer.getData('text/plain');
if (uri) {//如果拖拽的是image
var img = document.createElement('img');
img.setAttribute('src', uri);
target.appendChild(img);
} else if (text) {//如果拖拽的是text
var textNode = document.createTextNode(text);
target.appendChild(textNode);
}
});
</script>