原生拖放
拖放,将一个元素从一个位置拖放到另一个位置。最有意思的就是在框架间、应用间、窗口拖放网页元素。
拖放事件
拖放事件的关键在于 是确定在什么地方发生了拖放事件,有的事件是发生在被拖放的元素上,有的事件是发生在放置目标上。
拖动某元素时,会发生以下事件:
1、dragstart
2、drag
3、dragend
按下鼠标并开始托动鼠标时,会在被拖动元素上触发dragstart事件,这时鼠标会变成"不能放"的符号,表示不能放在自己上面。拖动开始时,通过ondragstart事件处理程序来执行JavaScript代码。
触发ondragstart后,随即触发drag事件,drag事件会在元素被拖动期间连续触发,拖动结束即松开鼠标按键后,此时无论是否放在有效目标上,还是放在无效目标上,均触发dragend事件。
当某个元素被拖放到一个有效的放置目标时,会触发以下事件:
1、dragenter
2、dragover
3、dragleave或drop
只要元素被拖放到(进入有效目标区域内)有效放置目标上,就会触发dragenter事件,紧接着触发dragover事件,无论是放置到了有效目标上,还是在有效目标上移动,均会触发dragover事件。如果将元素托出有效目(托出有效目标区域外)标会触发dragleave事件,而不会触发dragover事件,当元素被放在了目标上就会触发drop事件。
自定义放置目标
在拖动元素经过一些无效放置目标时,会出现一个特殊的光标即圆圈中带有红色的反斜线。表示该目标不能放置元素。我们可以通过改写dragenter和dragover的默认行为,让任何元素均是有效放置目标。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript之Canvas</title>
</head>
<body>
<div id="drag">有效的放置目标</div>
<script>
var drag = document.getElementById("drag");
drag.ondraenter = function (event) {
event.preventDefault(); //阻止dragenter的默认行为
};
drag.ondragover = function (event) {
event.preventDefault(); //阻止dragover的默认行为
};
</script>
</body>
</html>
此时,我们会发现,当我们拖动元素到<div>上时,会默认地打开元素的URL或元素文本或更是出错,这是drop的默认行为,这种默认行为有时会影响拖放操作。
可以阻止drop的默认行为:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript之Canvas</title>
</head>
<body>
<div id="drag">有效的放置目标</div>
<script>
var drag = document.getElementById("drag");
drag.ondraenter = function (event) {
event.preventDefault(); //阻止dragenter的默认行为
};
drag.ondragover = function (event) {
event.preventDefault(); //阻止dragover的默认行为
};
//阻止drop的默认行为即打开URL或元素文本内容
drag.ondrop = function (event) {
event.preventDefault();
};
</script>
</body>
</html>
这样的话,当拖动元素到<div>上时,就不会打开元素的URL或元素的文本内容了。这样能更好地支持拖放操作。
dataTransfer属性
//设置和接收文本数据
event.dataTransfer.setData("text", "some text");
var text = event.getData("text"); //参数是setData()的第一个参数
//设置和接收URL
event.dataTransfer.setData("URL", "http://www.sina.com.cn");
var url = event.getData("URL");
在拖动文本框的文本时,会触发setData()方法,将文本以“text”格式保存在dataTransfer中。同理在拖动图像和链接时,会将其以"URL"格式保存在dataTransfer中。然后在有效放置目标通过getData()读取数据。
draggable可拖动
HTML5中为所有元素添加了一个新的draggable属性,该属性可以规定元素是否可拖动。当属性值为"true"时,表示可拖动。
<img src="smile.png" draggable="false" alt="img">
这个例子表示页面中的图片不可拖动。
举一个简单的拖放例子:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript之Canvas</title>
<style>
#div1, #div2 {
float: left;
width: 200px;
height: 100px;
border: 1px solid #ccc;
margin-right: 5px;
}
</style>
</head>
<body>
<div id="div1" οndrοp="drop(event)" οndragοver="allowDrop(event)">
<p id="p1" draggable="true" οndragstart="drag(event)">被拖放的元素</p>
</div>
<div id="div2" οndrοp="drop(event)" οndragοver="allowDrop(event)"></div>
<script>
function allowDrop (event) {
event.preventDefault(); //阻止默认行为
}
/*当拖动时,将数据以"Text"格式保存在dataTransfer中
这里面传递的数据就是触发drag事件的元素的id
*/
function drag (event) {
event.dataTransfer.setData("Text", event.target.id);
}
//当将元素放置有效目标时,阻止drop的默认行为,并读取dataTransfer中的数据,
//以及将数据添加到目标位置中
function drop (event) {
event.preventDefault();
var data = event.dataTransfer.getData("Text");
event.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
效果:
我们可以看到<p>元素在两个<div>中来回被拖动,其中,setData()和getData之间传递的数据就是触发drag事件的元素的id,也就是<p>元素的id。
当开始用鼠标拖动元素时,触发了ondragstart事件处理程序,将该元素的id保存在了dataTransfer对象中。再将被托元素放于有效的目标位置时,触发ondrop事件处理程序,此程序读取setData()中的数据即被托元素的id,并将该元素插入到目标位置(该目标位置触发了ondrop事件处理程序)。