拖放事件

HTML5为所有的HTML元素新增了一个draggable属性,表示元素是否允许拖动。默认情况下,图像、链接和文本是可以拖动的,文本只有在被选中的情况下才能拖动。 需要注意的是在ff下只加**draggable="true"**还不能实现拖放,需要做一些处理,大多数浏览器会为正被拖动的元素创建一个半透明的副本,这个副本始终跟着光标移动。

元素拖放时会触发一系列的拖放事件

  1. (1)拖放元素事件:事件对象为被拖放的元素
  2. ondragstart 拖放开始触发
  3. ondragend 拖放结束触发
  4. ondrag 拖放期间触发,连续触发(无论拖放元素放在有效目标还是无效目标,都会触发)
  5. (2)目标元素事件:事件对象为目标元素
  6. ondragenter 拖放元素进入目标元素触发
  7. ondragleave 拖放元素离开目标元素触发
  8. ondragover 拖放元素进入目标元素和离开目标元素之间触发,连续触发
  9. ondrop 在目标元素上释放鼠标时触发,要想触发drop事件就必须在dragover当中阻止默认事件
  10. (3)事件执行顺序:
  11. drop不触发的时候
  12. dragstart > drag > dragenter > dragover > dragleave > dragend
  13. drop触发的时候 在dragover中阻止默认事件
  14. dragstart > drag > dragenter > dragover > drop > dragend

示例代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>拖放事件</title>
  6. <style type="text/css">
  7. ul li {
  8. width: 100px;
  9. height: 40px;
  10. background: #ff0;
  11. margin-bottom: 8px;
  12. list-style: none;
  13. }
  14. div {
  15. width: 200px;
  16. height: 200px;
  17. background: #f00;
  18. margin: 100px 0 0 100px;
  19. }
  20. </style>
  21. </head>
  22. <script>
  23. window.onload = function () {
  24. var oUl = document.getElementById('ul1');
  25. var oDiv = document.getElementById('div1');
  26. var oLi = oUl.getElementsByTagName('li')[0];
  27. var i = 0;
  28. // 拖放元素事件
  29. oLi.ondragstart = function () {
  30. this.style.background = 'blue';
  31. }
  32. oLi.ondragend = function () {
  33. this.style.background = 'yellow';
  34. }
  35. oLi.ondrag=function (){
  36. //连续触发
  37. document.title=i++;
  38. }
  39. // 目标元素事件,通过重写dragenter和dragleave方法来自定义目标元素背景颜色
  40. oDiv.ondragenter=function (){
  41. this.style.background='green';
  42. }
  43. oDiv.ondragleave=function (){
  44. this.style.background='red';
  45. }
  46. // 要想触发drop事件就必须在dragover当中阻止默认事件
  47. oDiv.ondragover = function () {
  48. console.log(i);
  49. return false;
  50. }
  51. // 在目标元素上释放鼠标时触发
  52. oDiv.ondrop = function () {
  53. this.style.background = '#000';
  54. }
  55. };
  56. </script>
  57. <body>
  58. <ul id="ul1">
  59. <li draggable="true">拖放元素</li>
  60. </ul>
  61. <div id="div1">目标元素</div>
  62. </body>
  63. </html>

解决ff下不能拖放的问题

要解决ff下不能拖放的问题,必须在ondragstart事件中设置dataTransfer对象的setData方法,dataTransfer对象是event对象下的一个属性,需要通过event对象访问 ,下文会详细说明dataTransfer对象。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>ff下不能拖放的问题</title>
  6. <style type="text/css">
  7. ul li{width: 100px;height: 40px;background: #ff0;margin-bottom:8px;list-style: none; }
  8. div{width: 100px;height: 100px;background: #f00;margin:300px 0 0 300px;}
  9. </style>
  10. </head>
  11. <script>
  12. window.onload=function (){
  13. var oUl=document.getElementById('ul1');
  14. var oDiv=document.getElementById('div1');
  15. var aLi=oUl.getElementsByTagName('li');
  16. // 拖放元素事件
  17. for (var i = 0; i < aLi.length; i++) {
  18. aLi[i].ondragstart=function (ev){
  19. ev.dataTransfer.setData('name','gongyz');
  20. }
  21. }
  22. // 目标元素事件
  23. oDiv.ondragover=function (){
  24. return false; // 要想触发ondrop事件,必须在onondragover中阻止默认事件
  25. }
  26. oDiv.ondrop=function (ev){
  27. console.log(ev.dataTransfer.getData('name'))
  28. }
  29. }
  30. </script>
  31. <body>
  32. <ul id="ul1">
  33. <li draggable="true">a</li>
  34. <li draggable="true">b</li>
  35. <li draggable="true">c</li>
  36. </ul>
  37. <div id="div1"></div>
  38. </body>
  39. </html>

DataTransfer 对象

概述

DataTransfer 对象用来保存,通过拖放动作,拖动到浏览器的数据。它可以保存一项或多项数据、一种或者多种数据类型。

这个对象在所有的拖放事件属性dataTransfer中都是可用的,但是不能单独创建,也就是说,在进行拖放操作的时候,会自动创建一个dataTransfer对象,这个对象作为拖放事件的事件对象的一个属性,保存了当前拖放操作的数据。

方法

setData(key,value) :设置拖放时要传递的数据(拖放元素)

getData(key):获取拖放时传递的数据(目标元素)

setDragImage(DOMElement image,x,y) :使用自定义的图片作为拖放时副本 (该方法接收三个参数 指定的元素,坐标X,坐标Y)

属性

files:用来获取外部拖放进来的文件,返回一个类数组的FileList对象

拖放删除元素

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>拖放删除元素</title>
  6. <style type="text/css">
  7. ul li{width: 100px;height: 30px;margin:8px;background: #ff0;}
  8. div{width: 200px;height: 200px;margin:100px 0 0 100px;background: #f00;}
  9. </style>
  10. </head>
  11. <script>
  12. window.onload=function (){
  13. var oUl=document.getElementsByTagName('ul')[0];
  14. var oDiv=document.getElementsByTagName('div')[0];
  15. var aLi=oUl.getElementsByTagName('li');
  16. for (var i = 0; i < aLi.length; i++) {
  17. aLi[i].index=i;
  18. aLi[i].ondragstart=function (ev){
  19. ev.dataTransfer.setData('data',this.index);
  20. }
  21. }
  22. oDiv.ondragover=function (){
  23. return false;//要想触发ondrop事件,必须在onondragover中阻止默认事件
  24. }
  25. oDiv.ondrop=function (ev){
  26. // 拿到索引值后删除对应的元素
  27. var _index=ev.dataTransfer.getData('data');
  28. oUl.removeChild(aLi[_index]);
  29. for (var i = 0; i < aLi.length; i++) {
  30. aLi[i].index = i;
  31. }
  32. }
  33. }
  34. </script>
  35. <body>
  36. <ul>
  37. <li draggable="true">a</li>
  38. <li draggable="true">b</li>
  39. <li draggable="true">c</li>
  40. <li draggable="true">d</li>
  41. </ul>
  42. <div></div>
  43. </body>
  44. </html>

自定义拖放副本

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>dataTransfer对象详解</title>
  6. <style type="text/css">
  7. ul li{width: 100px;height: 40px;background: #ff0;margin-bottom:8px;list-style: none; }
  8. div{width: 100px;height: 100px;background: #f00;margin:300px 0 0 300px;}
  9. </style>
  10. </head>
  11. <script>
  12. window.onload=function (){
  13. /*
  14. setDragImage方法 使用自定义的图片作为拖放时副本
  15. 该方法接收三个参数 指定的元素,坐标X,坐标Y
  16. */
  17. var oUl=document.getElementById('ul1');
  18. var oDiv=document.getElementById('div1');
  19. var aLi=oUl.getElementsByTagName('li');
  20. var oImg=document.getElementsByTagName('img')[0];
  21. // 拖放元素事件
  22. for (var i = 0; i < aLi.length; i++) {
  23. aLi[i].index=i;
  24. aLi[i].ondragstart=function (ev){
  25. var ev=ev||event;
  26. this.style.background='blue';
  27. ev.dataTransfer.setData('name','leo');
  28. ev.dataTransfer.setDragImage(oImg,0,0)
  29. }
  30. }
  31. //目标元素
  32. oDiv.ondragover=function (){
  33. return false; // 要想触发drop事件就必须在dragover当中阻止默认事件
  34. }
  35. oDiv.ondrop=function (){
  36. console.log(123)
  37. }
  38. };
  39. </script>
  40. <body>
  41. <ul id="ul1">
  42. <li draggable="true">a</li>
  43. <li draggable="true">b</li>
  44. <li draggable="true">c</li>
  45. </ul>
  46. <div id="div1"></div>
  47. <img src="xxx.png">
  48. </body>
  49. </html>

File和FileReader对象

File是一个是特殊类型的Blob对象,保存了和文件有关的信息。File 对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以是来自由拖放操作生成的DataTransfer对象中的files属性,这个属性就是一个类数组的FileList对象。

FileReader 用来读取通过dataTransfer对象的files属性获取的外部文件 ,将文件读取为Data URL格式,读取的结果保存在result属性中,如果是图片,返回base64格式的图片数据 。

结合之前的拖放操作和DataTransfer对象,我们就可以实现拖放上传文件功能,下面的代码示例介绍了FileReader接口的使用方法:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>图片预览功能</title>
  6. <style type="text/css">
  7. div{width: 300px;height: 300px;background: #f00;margin:100px 0 0 200px;}
  8. </style>
  9. </head>
  10. <script>
  11. window.onload=function (){
  12. /*
  13. fileReader对象 用来读取通过dataTransfer对象的files属性获取的文件
  14. var fd = new FileReader();
  15. readAsDataURL()方法 参数为要读取的文件对象,将文件读取为DataURL格式
  16. onload事件 当读取文件完成的时候触发此事件
  17. fd.result 取读取的文件数据,如果是图片,返回base64格式的图片数据
  18. */
  19. var oDiv=document.getElementById('div1');
  20. var oUl=document.getElementsByTagName('ul')[0];
  21. //目标元素
  22. oDiv.ondragover=function (){
  23. return false;// 要想触发drop事件就必须在dragover当中阻止默认事件
  24. }
  25. oDiv.ondrop=function (ev){
  26. var ev=ev||event;
  27. var fs=ev.dataTransfer.files;
  28. for (var i = 0; i < fs.length; i++) {
  29. if (fs[i].type.indexOf('image') !== -1) {
  30. var fd=new FileReader();
  31. fd.readAsDataURL(fs[i]);
  32. fd.onload=function (){
  33. var oLi=document.createElement('li');
  34. oLi.innerHTML='<img src="'+this.result+'">';
  35. oUl.appendChild(oLi);
  36. }
  37. }else{
  38. alert('请上传图片类型!!!');
  39. }
  40. }
  41. return false;
  42. }
  43. };
  44. </script>
  45. <body>
  46. <div id="div1">请把文件拖放在此处</div>
  47. <ul></ul>
  48. </body>
  49. </html>