拖放(Drag 和 drop)是 HTML5 标准的组成部分,任何元素都能够拖放。
下面,我们先分别研究拖放事件的不同部分。
首先,设置元素的样式和HTML结构:
<style>
#ele { width: 50px;height: 50px;background: #f00;}
#box{width:500px;height:300px;border:1px solid #ccc;margin:200px 400px;}
</style>
<div id='ele' draggable="true">拖动对象</div>
<div id='box'>容器</div>
设置元素为可拖放
为了使元素可拖动,把 draggable 属性设置为 true :
<div id='ele' draggable="true"></div>
在拖动之前,我们还要在JS中获取二个元素:
var ele=document.getElementById('ele');
var box=document.getElementById('box');
拖动什么 - ondragstart 和 setData()
当元素被拖动时,会发生什么?ondragstart 指的是拖动发生时监听的事件。
接下来,可以先测试一下:
<script>
ele.ondragstart=function(e){
console.log(111);
}
</script>
测试结果很清楚,一旦拖动了ele,控制台就会输出字符。
事实上,我们准备使用ondragstart 调用一个函数,它规定了被拖动的数据。
dataTransfer.setData() 方法可以用来设置被拖数据的数据类型和值:
<script>
ele.ondragstart=function(e){
e.dataTransfer.setData('id',e.target.id)
}
</script>
在这里,传递的数据名是 "id",值是可拖动的元素:e.target.id。
放到何处 - ondragover
ondragover 事件规定在何处放置被拖动的数据。
ondragover 事件是写在容器上,而不是拖动的元素。我们也来测试一下:
<script>
box.ondragover=function(e){
// e.preventDefault();
console.log('ffff');
}
</script>
我们发现,当把上面的小方块拖动到容器中时,控制台输出了字符。
默认地,无法将数据/元素放置到其他元素中。如果需要设置允许放置,我们必须阻止对元素的默认处理方式。
这要通过调用 ondragover 事件的 event.preventDefault() 方法:
进行放置 - ondrop
当放置被拖数据时,会监听ondrop 事件,ondrop事件也是写在容器上。
让我们也来测试一下这个事件:
<script>
box.ondrop=function(e){
console.log('ffff');
}
</script>
这一次,当我们把上面的松开小方块时,控制台输出了字符。
ondrop 属性调用了一个函数:
box.ondrop=function(e){
e.preventDefault();
var data=e.dataTransfer.getData("id");
e.target.appendChild(document.getElementById(data));
}
对这一段代码我们解释一下:
调用 preventDefault() 来避免浏览器对数据的默认处理(drop 事件的默认行为是以链接形式打开)
通过 dataTransfer.getData("id") 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据。
被拖数据是被拖元素的 id ,我们使用data=e.dataTransfer.getData("id")来获得。
把被拖元素追加到容器(目标元素)中
JS完整代码如下:
<script>
var ele=document.getElementById('ele');
var box=document.getElementById('box');
ele.ondragstart=function(e){
e.dataTransfer.setData('id',e.target.id)
}
box.ondragover=function(e){
e.preventDefault();
}
box.ondrop=function(e){
e.preventDefault();
var data=e.dataTransfer.getData("id");
e.target.appendChild(document.getElementById(data));
}
</script>
下面我们给一个案例,实现一个方块的来回拖动:
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#div1,#div2{float:left;width:198px; height:66px; margin:8px;border:1px solid #aaa;}
#drag1{width:40px;height:40px;background:#f00;}
</style>
<script type="text/javascript">
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<div draggable="true" ondragstart="drag(event)" id="drag1" />
</div>
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>