使用拖放主要可实现两种功能:(1).从计算机上将文件拖到网页上。(2).将元素拖到同一页面的其他元素中。
将元素拖放到页面上,需要以下几个步骤:
1.设置你想拖动的任何HTML元素的draggable属性。
2.给任何可拖动的HTML元素的draggable事件添加事件监听器.
3.给任何接受拖放元素的dragover 和 drop 添加事件监听器。
draggable不是一个布尔值,必须明确的指定为TRUE时,元素才可以拖动。此外div元素需要设置draggable属性。而img元素以及设置了href属性的a元素都是默认可拖动的
如下:
html代码:
<div id = "srcarea">
<img src = "./images/12.1.png" id = "item1" class = "item" />
<img src = "./images/12.2.png" id = "item2" class = "item"/>
<img src = "./images/12.3.png" id = "item3" class = "item" />
<div id = "item4" class = "item" draggable = "true" style="width: 100px;height: 100px; background-color:red"></div>
</div>
<div id = "droparea"></div>
srcarea为原位置,droparea为目标位置。
将以上代码设置样式:
css代码:
<style type="text/css">
*{
margin: 0px;
padding: 0px;
}
#srcarea{
width: 440px;
height: 100px;
}
#srcarea.item{
float: left;
}
#item4{
display:inline-block;
}
#droparea{
width: 100px;
height: 100px;
border:1px solid red;
}
.item{
width: 100px;
height: 100px;
}
</style>
接下来就要进行js部分代码的编写。首先得明白在拖动对象元素有哪些事件,在接受方元素有哪些事件。以下列出了相关事件
对照上面的表,可以知道。要实现拖放功能至少需要实现 dragstart、dragenter、dragover、drop四种事件处理。
移动前的效果图
首先为拖动元素追加事件处理的代码:
var srcarea = document.getElementById("srcarea");
var els = document.querySelectorAll(".item");
for(var i = 0; i < els.length; i++){
els[i].addEventListener("dragstart", function(event){
var elm = event.target;
event.dataTransfer.setData("Text", elm.id);
event.stopPropagation();
},false);
}
在这里了解一下dataTransfer对象的setData()方法:
该方法接受两个参数:①.可拖动元素的存储数据类型,在这儿为‘Text‘
②.数据值本身,在这儿是文本类型的id值.
event.dataTransfer.setData(“Text”, elm.id)设置拖动元素的id属性,可以在drop事件中判别哪个元素被拖动了。
event.stopPropagation().这个方法是防止事件向父级冒泡。即防止事件传导到父级。如果父级元素也有拖动事件,那么在拖动子元素时,就会触发父元素的事件。会发生意想不到的错误。
接下来就是给接受方添加事件处理
var droparea = document.getElementById('droparea');
droparea.addEventListener("dragenter", function(event){
event.preventDefault();
},false);
droparea.addEventListener("dragover", function(event){
event.preventDefault();
},false);
event.preventDefault();抑制浏览器的默认动作
这两个事件处理中,如果不对浏览器的默认动作进行抑制,将实现不了拖放功能。
最后一步就是真正实现拖放功能的代码。
droparea.addEventListener("drop", function(event){
var elm = event.target;
var id = event.dataTransfer.getData("Text"); //通过存储数据类型获得相应的ID值
var target = document.getElementById(id);
if(target){
droparea.appendChild(target);
}
event.preventDefault();
},false);
上面这些代码都是在页面加载完成触发的。
但是最后的代码存在一个问题,就是如果你只想向接收方拖动一个元素时,上面的代码可以将拖动方的元素依次都可以拖动到接收方(即便接收方容器的大小不够,它也会充满再溢出。),所以需要对上面的代码进行改造实现接收方只能容纳一个元素。若继续拖动,只会替换掉以前拖入的,将现在的放上去,以前的回到原地方。
在这里用到了本地数据保存的对象localStorage
droparea.addEventListener("drop", function(event){
var preId = localStorage.getItem("oldId");
var preSrc = localStorage.getItem("oldSrc");
if(droparea.querySelectorAll(".item").length != 0){
if(preSrc !== undefined){
var image = document.createElement("img");
image.className = "item";
image.id = preId;
image.src = preSrc;
srcarea.appendChild(image);
}
if(preSrc === undefined)
{
var div = document.createElement("div");
div.className = "item";
div.id = preId;
srcarea.appendChild(div);
}
$("#droparea").empty();
}
//如果接收方中无元素就从这儿执行。
var elm = event.target;
var id = event.dataTransfer.getData("Text");
var target = document.getElementById(id);
var imgSrc = target.src;
if(target){
droparea.appendChild(target);
}
localStorage.removeItem("oldSrc");
localStorage.removeItem("oldId");
localStorage.setItem("oldId",id);
localStorage.setItem("oldSrc",imgSrc);
event.preventDefault();
},false);
在上面代码中首先用droparea.querySelectorAll(“.item”)判断了接收方容器中元素的数量是不是0。
localStorage.removeItem("oldSrc");
localStorage.removeItem("oldId");
localStorage.setItem("oldId",id);
localStorage.setItem("oldSrc",imgSrc);
这四行代码,用本地数据保存的对象localStorage先将上一个元素的值移除掉,保存刚刚拖动的元素的src和id值。
再进行第二次拖放时,首先会判断接收方中元素的个数为不为0。不为0的话,就先判断上一个的src是不是undefined。因为我们拖动的对象中除了图片还有一个div元素。div元素的src为undefined。如果是undefined就创建一个div元素。(因为它即将要被替换掉。)在创建的div中添加各种属性,最后添加到原来的父容器中。
如果上一个元素的src不是undefined,说明是图片,我们即创建一个img元素,设置好属性后。append在它原来的父容器中。
移动的效果图1
用红色的方框替换星星图片。
移动的效果图2。
这样一次只允许容纳一个元素的拖动方法就完成了。