1. 拖放(drag和drop)是html5标准的组成部分。
2. 拖放
2.1. 拖放是一种常见的特性, 即抓取对象以后拖到另一个位置。
2.2. 在html5中, 拖放是标准的一部分, 任何元素都能够拖放。
3. 设置元素为可拖放
3.1. 首先, 为了使元素可拖动, 把draggable属性设置为true。draggable属性可以在任何元素上设置, 也就是说几乎所有的元素都可以进行拖动操作。
3.2. 设置一个图片可拖动:
<img draggable="true" />
3.3. 设置一个文本可拖动:
<span draggable="true" />可拖动文本</span>
4. 拖动什么 - ondragstart和setData()
4.1. 当元素被拖动时, 会发生ondragstart事件, 我们为ondragstart属性指定一个myDragStart(event)函数, 它规定了被拖动的数据。dataTransfer.setData()方法设置被拖数据的数据类型和值:
function myDragStart(dragEven){
dragEven.dataTransfer.setData("text/plain", dragEven.target.id);
}
<img id="drag1" src="drag.gif" draggable="true" ondragstart="myDragStart(event)" />
4.2. 在这个例子中, 设置被拖动的数据类型是"text/plain", 值是可拖动元素的id("drag1")。
5. 放到何处 - ondragover
5.1. ondragover事件规定在何处放置被拖动的数据。
5.2. 默认地, 无法将数据/元素放置到其他元素中。如果需要设置允许放置, 我们必须阻止对元素的默认处理方式。这要通过调用ondragover事件的event.preventDefault()方法:
function myDragOver(dragEven){
dragEven.preventDefault();
}
<div id="div1" ondragover="myDragOver(event)"></div>
6. 进行放置 - ondrop
6.1. 当放置被拖数据时, 会发生drop事件。
function myDrop(dragEven){
dragEven.preventDefault();
var id = dragEven.dataTransfer.getData("text");
dragEven.target.appendChild(document.getElementById(id));
}
<div id="div1" ondrop="myDrop(event)" ondragover="myDragOver(event)"></div>
7. html5拖放例子
7.1. 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>拖拽实例</title>
<style type="text/css">
#div1 {width: 198px; height: 66px; padding: 10px; border: 1px solid #aaaaaa;}
</style>
<script type="text/javascript">
function myDragStart(dragEven){
dragEven.dataTransfer.setData("text/plain", dragEven.target.id);
}
function myDragOver(dragEven){
dragEven.preventDefault();
}
function myDrop(dragEven){
dragEven.preventDefault();
var id = dragEven.dataTransfer.getData("text");
if(id === "") return;
dragEven.target.appendChild(document.getElementById(id));
}
</script>
</head>
<body>
<p>请把W3School的图片拖放到矩形中:</p>
<div id="div1" ondrop="myDrop(event)" ondragover="myDragOver(event)"></div><br />
<img id="drag1" src="drag.gif" draggable="true" ondragstart="myDragStart(event)" />
</body>
</html>
7.2. 效果图
8. DragEvent事件对象
8.1. DragEvent是一个表示drag和drop交互的DOM event接口。用户通过将指针设备(如: 鼠标)放在目标的表面开始拖动, 然后拖动指针到一个新的位置(其他DOM元素)。应用程序自动的解析拖放交互。
8.2. DragEvent接口从MouseEvent和Event那儿继承属性。
8.3. DragEvent并不是一个单一的事件, 它包含了多个事件, 这些事件分别是: dragstart、drag、dragenter、dragover、dragleave、drop和dragend。
8.4. DragEvent.dataTransfer是一个只读属性, 在拖放交互期间传输的数据。
9. ondragstart事件
9.1. ondragstart事件在用户开始拖动时触发。这个事件的目标元素是被拖的那个元素, 在这些事件中, dragstart事件最先触发。该事件可冒泡, 可取消默认行为。
9.2. 为了让元素可拖动, 需要使用html5 draggable属性。
9.3. 链接和图片默认是可拖动的, 不需要draggable属性。
9.4. 在拖放的过程中会触发以下事件:
9.4.1. 在拖动目标上触发事件(源元素):
- ondragstart: 用户开始拖动元素时触发。
- ondrag: 元素正在拖动时触发。
- ondragend: 用户完成元素拖动后触发。
9.4.2. 释放目标时触发的事件:
- ondragenter: 当被鼠标拖动的对象进入其容器范围内时触发此事件。
- ondragover: 当某被拖动的对象在另一对象容器范围内拖动时触发此事件。
- ondragleave: 当被鼠标拖动的对象离开其容器范围内时触发此事件。
- ondrop: 在一个拖动过程中, 释放鼠标键时触发此事件。
9.5. 语法
9.5.1. html中:
<element ondragstart="myScript">
9.5.2. JavaScript中:
object.ondragstart=function(){myScript};
10. ondrag事件
10.1. ondrag事件在元素拖拽的过程中反复触发, 每一百毫秒触发一次。这事件的目标元素是被拖的那个元素, 该事件可冒泡, 可取消默认行为。
10.2. 语法
10.2.1. html中:
<element ondrag="myScript">
10.2.2. JavaScript中:
object.ondrag=function(){myScript};
11. ondragenter事件
11.1. ondragenter事件在被拖的元素进入一个合法的可drop目标时触发。这个事件的目标元素是这个可drop目标。该事件可冒泡, 可取消默认行为。
11.2. 语法
11.2.1. html中:
<element ondragenter="myScript">
11.2.2. JavaScript中:
object.ondragenter=function(){myScript};
12. ondragover事件
12.1. ondragover当被拖的元素在可drop目标范围内移动时反复触发这个事件, 一百毫秒触发一次。这个事件的目标元素是这个可drop目标。该事件可冒泡, 可取消默认行为。
12.2. 默认情况下, 数据/元素不能放置到其他元素中。如果要实现改功能, 我们需要防止元素的默认处理方法。我们可以通过调用event.preventDefault()方法来实现ondragover事件。
12.3. 语法
12.3.1. html中:
<element ondragover="myScript">
12.3.2. JavaScript中:
object.ondragover=function(){myScript};
13. ondragleave事件
13.1. ondragleave这个事件在被拖得元素离开合法的可drop目标时触发。这个事件的目标元素是这个可drop目标。该事件可冒泡, 不能取消默认行为。
13.2. 语法
13.2.1. html中:
<element ondragleave="myScript">
13.2.2. JavaScript中:
object.ondragleave=function(){myScript};
14. ondrop事件
14.1. ondrop当在可drop目标上松开拖动元素的指针设备时触发这个事件, 该事件的目标元素是这个可drop目标。drop事件在dragend事件触发之前触发。这个事件可冒泡, 可取消默认行为。
14.2. 语法
14.2.1. html中:
<element ondrop="myScript">
14.2.2. JavaScript中:
object.ondrop=function(){myScript};
15. ondragend事件
15.1. ondragend当拖拽结束时触发这个事件, 这个事件的目标元素是被拖的元素。在这些事件中dragend最后触发。该事件可冒泡, 不能取消默认行为。
15.2. 语法
15.2.1. html中:
<element ondragend="myScript">
15.2.2. JavaScript中:
object.ondragend=function(){myScript};
16. DataTransfer对象
16.1. DragEvent事件的dataTransfer属性是一个DataTransfer对象, 在这个对象中保存了拖拽操作过程中的数据, 它可能保存一个或者多个数据项。
17. DataTransfer.types
17.1. DataTransfer.types是只读属性。它返回一个我们在dragstart事件中设置的拖动数据格式的数组。格式顺序与拖动操作中包含的数据顺序相同。
17.2. 这些格式是指定数据类型或格式的Unicode字符串, 通常由MIME类型给出。
17.3. DataTransfer.types返回值是拖动操作中使用的数据格式数组。每种格式都是字符串类型。如果拖动操作不包含数据, 则此数组列表将为空。如果拖动操作中包含任何文件, 则其中一个类型将是Files。
17.4. <img>和<a>标签拖动操作有没有包含数据, 都返回['text/plain', 'text/uri-list', 'text/html']。
17.5. 拖动文件操作有没有包含数据, 都返回['Files']。
17.6. 例子
17.6.1. 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>DataTransfer.types</title>
<style type="text/css">
#div1 {width: 198px; height: 66px; padding: 10px; border: 1px solid #aaaaaa;}
</style>
<script type="text/javascript">
function myDragStart(dragEven){
dragEven.dataTransfer.setData("text/plain", dragEven.target.id);
}
function myDragOver(dragEven){
dragEven.preventDefault();
}
function myDrop(dragEven){
dragEven.preventDefault();
var types = dragEven.dataTransfer.types;
console.log(types);
}
</script>
</head>
<body>
<p>请把W3School的图片、超链接、文本或者外部文件拖放到矩形中:</p>
<div id="div1" ondrop="myDrop(event)" ondragover="myDragOver(event)"></div><br />
<img id="img1" src="drag.gif" draggable="true" ondragstart="myDragStart(event)" />
<a href="#" id="a1" draggable="true" ondragstart="myDragStart(event)">可拖拽超链接</a>
<span id="span1" draggable="true" ondragstart="myDragStart(event)">可拖拽文本</span>
</body>
</html>
17.6.2. 效果图
17.6.3. 拖动操作没有包含数据, 效果图
18. DataTransfer.setData()
18.1. DataTransfer.setData()方法用来设置拖放操作的drag data到指定的数据和类型。
18.2. 如果给定类型的数据不存在, 则将其添加到拖动数据存储的末尾, 使得types列表中的最后一个项目将是新类型。
18.3. 如果给定类型的数据已经存在, 现有数据将被替换为相同的位置。也就是说, 替换相同类型的数据时types列表的顺序不会更改。
18.4. 语法
void dataTransfer.setData(format, data);
18.5. 参数format表示要添加到drag object的拖动数据的类型。
18.6. 参数data表示要添加到drag object的数据。
19. DataTransfer.getData()
19.1. DataTransfer.getData()方法获取指定类型的拖放数据。如果拖放行为没有操作任何数据, 会返回一个空字符串。
19.2. 语法
String dataTransfer.getData(format);
19.3. 参数format表示要添加到drag object的拖动数据的类型。
19.4. 返回值是一个给定类型的String格式的数据。如果没有操作数据或者没有指定操作数据的类型, 都会返回一个空字符串。
20. DataTransfer.clearData()
20.1. DataTransfer.clearData()方法删除给定类型的拖动操作的drag data。如果给定类型的数据不存在, 则此方法不执行任何操作。
20.2. 如果调用此方法没有参数, 则将删除所有类型的数据。
20.3. 此方法不会从拖动操作中删除文件, 因此如果有任何文件包含在对象的DataTransfer.types列表中, 仍然可能有一个类型为"Files"的条目在拖动。
20.4. 语法
DataTransfer.clearData([format]);
21. DataTransfer.files
21.1. DataTransfer.files属性在拖动操作中表示文件列表。如果操作不包含文件, 则此列表为空。此功能可用于将文件从用户桌面拖动到浏览器。
21.2. 语法
dataTransfer.files;
22. DataTransfer.items
22.1. DataTransfer的items属性只读, 是拖动操作中数据传输项的列表。该列表包含了操作中每一项目的对应项, 如果操作没有项目, 则列表为空。
22.2. 语法
var itemList = dataTransfer.items;
22.3. 返回一个DataTransferItemList对象, 包含了表示拖动操作中被拖动项的DataTransferItem对象, 每一个拖动项对应一个列表项。如果拖动操作中没有数据, 则列表为空。
23. DataTransferItem对象
23.1. DataTransferItem描述了一个拖拽项。在一个拖拽操作中, 每一个drag event都有一个dataTransfer属性, 它包含一个存有拖拽数据的list, 其中每一项都是一个DataTransferItem。
23.2. DataTransferItem.kind是一个只读属性, 表示拖拽项的种类string或是file。
23.3. DataTransferItem.type是一个只读属性, 表示拖拽项的类型, 一般是一个MIME类型。
23.4. DataTransferItem.getAsFile()
23.4.1. 如果DataTransferItem是一个文件, 那DataTransferItem.getAsFile()方法将返回拖拽项数据的File对象。如果拖拽项的数据不是一个文件, 则返回null。
23.4.2. 语法
var File = DataTransferItem.getAsFile();
23.5. DataTransferItem.getAsString()
23.5.1. DataTransferItem.getAsString()当DataTransferItem对象的kind属性是一个普通Unicode字符串时, 该方法会用DataTransferItem对象的kind属性作为入参来执行传入的回调函数。
23.5.2. 语法
dataTransferItem.getAsString(callback);
24. 例子
24.1. 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>DataTransfer.files和DataTransfer.items</title>
<style type="text/css">
#div1 {width: 198px; height: 66px; padding: 10px; border: 1px solid #aaaaaa;}
</style>
<script type="text/javascript">
function myDragStart(dragEven){
dragEven.dataTransfer.setData("text/plain", dragEven.target.id);
}
function myDragOver(dragEven){
dragEven.preventDefault();
}
function myDrop(dragEven){
dragEven.preventDefault();
var files = dragEven.dataTransfer.files;
for (let i = 0; i < files.length; i++) {
var f = files[i];
console.log('name: ' + f.name + ' size: ' + f.size + ', type: ' + f.type);
}
var items = dragEven.dataTransfer.items;
for (let i = 0; i < items.length; i++) {
if((items[i].kind == 'string') && (items[i].type.match('^text/plain'))){
items[i].getAsString(function (id){
console.log('id: ' + id);
});
} else if(items[i].kind == 'file'){
var f = items[i].getAsFile();
console.log('name: ' + f.name + ' size: ' + f.size + ', type: ' + f.type);
}
}
}
</script>
</head>
<body>
<p>请把W3School的图片、超链接、文本或者外部文件拖放到矩形中:</p>
<div id="div1" ondrop="myDrop(event)" ondragover="myDragOver(event)"></div><br />
<img id="img1" src="drag.gif" draggable="true" ondragstart="myDragStart(event)" />
<a href="#" id="a1" draggable="true" ondragstart="myDragStart(event)">可拖拽超链接</a>
<span id="span1" draggable="true" ondragstart="myDragStart(event)">可拖拽文本</span>
</body>
</html>
24.2. 效果图