拖拽(Drag/Drop)是个非常普遍的功能。你可以抓住一个对象,并且拖动到你想放置的区域。 很多javascript都类似实现了相关的功能,例如,jQueryUI的drag and drop组件。在HTML5中,拖拽(drag and drop)成为了标准操作,任何元素都支持。正因为这个功能太普遍了,所有的主流浏览器都支持这个操作。

启用拖拽 - draggable属性
      非常简单,只需要将一个元素的拖动属性修改为draggable,这个元素就支持拖动了,如下所示:

< img  draggable ="true"   /> 

拖动中数据的传递

拖动的过程中,我们往往需要传递相应的逻辑数据来完成转换的过程,这里主要是使用dataTransfer对象进行数据传递,下面先看看它的成员:
方法成员:

setData(format, data):把被拖动的数据赋值给dataTransfer对象。

format:一个String型参数,指定被拖动数据的类型。该参数取值可以是“Text”(文本类型)和“URL”(URL类型)。该参数是大小写无关的,所以传入"text"与"Text"是一样的。
      data:一个变体类型参数,指定被拖动的数据。该数据可以是文本,图片路径,URL等等。
      该函数有Boolean类型的返回值,true表示数据成功加到dataTransfer中,false代表不成功。如果需要,可以通过这个参数来决定是否应该继续执行某些逻辑。

getData(format):获取dataTransfer中存放的拖动数据。

format意义与setData中的一样,取值可以是"Text"(文本类型)和"URL"(URL类型)。

clearData(format):移除指定类型的数据。

这里的format除了上面可以指定的"Text"(文本类型)和"URL"(URL类型)外,还可以取下列值:file - 文件,html - html元素,image - 图片。
      这个方法可以用于去选择性的处理拖动的数据类型。

属性成员:

effectAllowed:设置或获取数据源元素中的数据可以执行的操作。

属性类型为字符串,取值范围如下:
          "copy"-复制数据.
          "link"-链接数据.
          "move"-移动数据
          "copyLink"-复制或链接数据,由目标对象来确定。
          "copyMove"-复制或移动数据,由目标对象来确定。
          "linkMove"-链接或移动数据,由目标对象来确定。
          "all"-所有的操作都是支持的。
          "none"-禁止拖动。
          "uninitialized"-默认值,采用默认的行为。

      注意设置effectAllowed为none以后,拖动是禁止的,但是鼠标形状还是显示没有可拖动的对象的形状,如果想不显示这个鼠标形状,则需要将window的event事件的属性returnValue设置为false。

dropEffect:设置或获取拖动的目标上允许的操作以及相关的鼠标形状。

属性类型为字符串,取值范围如下:
         "copy"-鼠标显示为复制时的形状;
         "link"-鼠标显示为连接的形状;
         "move"-鼠标显示为移动的形状。
         "none"(默认值)-鼠标显示为没有拖动的形状。

      effectAllowed指定了数据源支持的操作,所以通常在ondragstart事件中指定。dropEffect指定了拖动放置的目标支持的操作,所以与effectAllowed配合,通常在拖动的目标上的 ondragenter, ondragover和ondrop等事件中使用。

files:返回拖动的文件的列表FileList。
types:ondragstart中发送的数据(被拖动的数据)类型的列表。

dataTransfer对象的存在,使得在拖动的数据源和目标元素之间传递逻辑数据变成了可能。通常我们使用setData方法在数据源元素的ondragstart事件中提供数据,然后再目标元素中,使用getData方法获取数据。

拖动中触发的事件
      下面是一次拖拽会发生的事件,基本上事件的触发顺序也就是下面的顺序:

dragstart:要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素。
drag:拖拽元素时触发,这个事件对象是被拖拽元素。
dragenter:拖拽元素进入目标元素时触发,这个事件对象是目标元素。
dragover:拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素。
dragleave:拖拽某元素离开目标元素时触发,这个事件对象是目标元素。
drop:将被拖拽元素放在目标元素内时触发,这个事件对象是目标元素。
dragend:在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素。

基本上事件的参数event都会传入相关的元素,可以很方便的进行一些修改。这里,我们并不需要处理每个事件,通常只需要挂接主要的几个事件即可。

拖动开始 - ondragstart事件
      从这个事件传入的参数含有的信息非常丰富,从中可以很方便的获取到被拖动的元素(event.Target);从中可以设置被拖动数据(event.dataTransfer.setData);所以你可以很方便实现拖动的背后逻辑(当然你绑定的时候也可以传递其他的参数)。
拖动过程中 - ondrag,ondragover,ondragenter和ondragleave事件
      ondrag事件的对象是被拖拽元素,通常这个事件处理的比较少。ondragenter事件是当拖动进入当前元素时发生,ondragleave事件是在当拖动离开当前元素时发生,ondragover事件是在拖动在当前元素中移动时发生。
      这里只需要注意一点,因为默认情况下,浏览器是禁止元素drop的,所以为了让元素可以drop,需要在这个函数中返回false或者调用event.preventDefault()方法。如下面的例子所示。
拖动结束 - ondrop,ondragend事件
      当可拖动的数据被drop的时候,drop事件触发。drop结束后,dragend事件被触发,这个事件使用的也相对少一点。

看一个简单的例子:

<! DOCTYPE HTML >
< html >
< head >
< script  type ="text/javascript" >
   function  allowDrop(ev){
    ev.preventDefault();
  }
   function  drag(ev){
    ev.dataTransfer.setData( " Text " ,ev.target.id);
  }
   function  drop(ev){
     var  data = ev.dataTransfer.getData( " Text " );
    ev.target.appendChild(document.getElementById(data));
    ev.preventDefault();
  }
</ script >
</ head >
< body >
   < div  id ="div1"  ondrop ="drop(event)"  ondragover ="allowDrop(event)" ></ div >
   < img  id ="drag1"  src ="img_logo.gif"  draggable ="true"  ondragstart ="drag(event)"  width ="336"  height ="69"   />
</ body >
</ html >

文件拖拽
      上面的例子已经使用了dataTransfer的各种方法和属性,下面再看网上的另外一个有趣的应用:拖拽一个图片到网页上,然后在网页上显示。这个应用用到了dataTransfer的files属性。

<! DOCTYPE HTML >
< html >
< head >
  < meta  charset ="utf-8" >
     < title >HTML5拖放文件 </ title >
     < style >
  #section { font-family :  "Georgia", "微软雅黑", "华文中宋" ; }
        .container { display : inline-block ; min-height : 200px ; min-width : 360px ; color : #f30 ; padding : 30px ; border : 3px solid #ddd ; -moz-border-radius : 10px ; -webkit-border-radius : 10px ; border-radius : 10px ; }
  .preview { max-width : 360px ; }
  #files-list { position : absolute ; top : 0 ; left : 500px ; }
  #list { width : 460px ; }
  #list .preview { max-width : 250px ; }
  #list p { color : #888 ; font-size : 12px ; }
  #list .green { color : #09c ; }
     </ style >
</ head >
< body >
     < div  id ="section" >
         < p >把你的图片拖到下面的容器内: </ p >
         < div  id ="container"  class ="container" >
         </ div >
   < div  id  ="files-list" >
    < p >已经拖进过来的文件: </ p >
    < ul  id ="list" ></ ul >
   </ div >
     </ div >
  < script >
  if  (window.FileReader) {
   var  list  =  document.getElementById( ' list ' ),
   cnt  =  document.getElementById( ' container ' );

//  判断是否图片
   function  isImage(type) {
    switch  (type) {
    case   ' image/jpeg ' :
    case   ' image/png ' :
    case   ' image/gif ' :
    case   ' image/bmp ' :
    case   ' image/jpg ' :
     return   true ;
    default :
     return   false ;
   }
  }

//  处理拖放文件列表
   function  handleFileSelect(evt) {
   evt.stopPropagation();
   evt.preventDefault();

var  files  =  evt.dataTransfer.files;
    for  ( var  i  =   0 , f; f  =  files[i]; i ++ ) {
     var  t  =  f.type  ?  f.type :  ' n/a ' ,
     reader  =   new  FileReader(),
     looks  =   function  (f, img) {
      list.innerHTML  +=   ' <li><strong> '   +  f.name  +   ' </strong> ( '   +  t  +
        ' ) -  '   +  f.size  +   '  bytes<p> '   +  img  +   ' </p></li> ' ;
      cnt.innerHTML  =  img;
     },
     isImg  =  isImage(t),
     img;

//  处理得到的图片
     if  (isImg) {
     reader.onload  =  ( function  (theFile) {
       return   function  (e) {
       img  =   ' <img class="preview" src=" '   +  e.target.result  +   ' " title=" '   +  theFile.name  +   ' "/> ' ;
       looks(theFile, img);
      };
     })(f)
     reader.readAsDataURL(f);
    }  else  {
     img  =   ' "o((>ω< ))o",你传进来的不是图片!! ' ;
     looks(f, img);
    }
   }
  }
  
   //  处理插入拖出效果
   function  handleDragEnter(evt){  this .setAttribute( ' style ' ,  ' border-style:dashed; ' ); }
   function  handleDragLeave(evt){  this .setAttribute( ' style ' ,  '' ); }

//  处理文件拖入事件,防止浏览器默认事件带来的重定向
   function  handleDragOver(evt) {
   evt.stopPropagation();
   evt.preventDefault();
  }
  
  cnt.addEventListener( ' dragenter ' , handleDragEnter,  false );
  cnt.addEventListener( ' dragover ' , handleDragOver,  false );
  cnt.addEventListener( ' drop ' , handleFileSelect,  false );
  cnt.addEventListener( ' dragleave ' , handleDragLeave,  false );
  
 }  else  {
  document.getElementById( ' section ' ).innerHTML  =   ' 你的浏览器不支持啊,同学 ' ;
 }
  </ script >
</ body >
</ html >

这个例子中使用了html5中的文件读取API:FileReader对象;该对象提供了下列异步方法用于读取文件:
1. FileReader.readAsBinaryString(fileBlob)
  以二进制的方式读取文件,result 属性会包含一个文件的二进制的格式
2. FileReader.readAsText(fileBlob, opt_encoding)
  以文本的方式读取文件, result 属性将会包含一个文件的文本格式,默认解码参数是 “utf-8”。
3. FileReader.readAsDataURL(file)
  以URL形式读取文件result 将会包含一个文件的 DataURL 格式(图片通常用这种方式)。

当使用上面的方法读取文件后,会触发下列事件:

onloadstart,onprogress,onabort,onerror,onload,onloadend

这些事件都很简单,需要的时候挂接就可以了。看下面的代码示例:

function startRead() {  
   //  obtain input element through DOM 
  
   var file = document.getElementById('file').files[0];
   if(file){
    getAsText(file);
  }
}

function getAsText(readFile) {
   var reader =  new FileReader();  
   //  Read file into memory as UTF-16      
  reader.readAsText(readFile, "UTF-16");  
   //  Handle progress, success, and errors
  reader.onprogress = updateProgress;
  reader.onload = loaded;
  reader.onerror = errorHandler;
}

function updateProgress(evt) {
   if (evt.lengthComputable) {
     //  evt.loaded and evt.total are ProgressEvent properties
     var loaded = (evt.loaded / evt.total);
     if (loaded < 1) {
       //  Increase the prog bar length
       //  style.width = (loaded * 200) + "px";
    }
  }
}

function loaded(evt) {  
   //  Obtain the read file data    
   var fileString = evt.target.result;
   //  Handle UTF-16 file dump
   if(utils.regexp.isChinese(fileString)) {
     // Chinese Characters + Name validation
  }
   else {
     //  run other charset test
  }
   //  xhr.send(fileString)     
}

function errorHandler(evt) {
   if(evt.target.error.name == "NotReadableErr") {
     //  The file could not be read
  }
}

这里也简单说一下:普通的文件下载使用的就是window.open方法,例如:

window.open('http://aaa.bbbb.com/ccc.rar','_blank')

实用参考:
官方文档:http://www.w3schools.com/html5/
一个不错的教程网站:http://html5.phphubei.com/html5/features/DrapAndDrop/
MSDN帮助:http://msdn.microsoft.com/en-us/library/ms535861(v=vs.85).aspx
文件拖拽详述:http://www.html5rocks.com/zh/tutorials/file/dndfiles/
文件拖拽并上传:http://www.chinaz.com/design/2010/0909/131984.shtml
文件拖拽上传完整例子:http://www.cnblogs.com/liaofeng/archive/2011/05/18/2049928.html
文件下载的例子:http://hi.baidu.com/guo_biru/item/2d7201c012b6debd0c0a7b05
window.open攻略:http://www.cnblogs.com/liulf/archive/2010/03/01/1675511.html
window.open参数:http://www.koyoz.com/blog/?action=show&id=176

转载于:https://www.cnblogs.com/dxy1982/archive/2012/08/17/2626515.html

突袭HTML5之Javascript API扩展4 - 拖拽相关推荐

  1. html dragover获得拖拽对象,突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述

    拖拽(Drag/Drop)是个非常普遍的功能.你可以抓住一个对象,并且拖动到你想放置的区域.很多javascript都类似实现了相关的功能,例如,jQueryUI的draganddrop组件.在HTM ...

  2. Vue结合HTML5拖放API 实现目录拖拽~

    拖放事件 dom被拖拽--->经过一些dom--->到达指定dom 被拖拽的dom:(源对象) dragstart 源对象被拖拽 drag 源对象拖拽过程中 dragend 源对象拖拽结束 ...

  3. JavaScript中随着鼠标拖拽而移动的块

    这里要设置一个div块,你按住它拖拽,它会随着你的鼠标走,比如常见的登录框. 给这个div设置简单的样式: 由于div是要跟着鼠标活动的,所以必须把position设置为绝对定位,也就是位置可以改变才 ...

  4. Javascript实现重力弹跳拖拽运动效果

    声明: By:GenialX 个人主页:胡旭博客 - www.ihuxu.com QQ:2252065614 演示地址: http://www.ihuxu.com/project/gcdmove/ 调 ...

  5. JavaScript案例——实现鼠标拖拽回放

    鼠标拖动box,点击"点击回放拖动轨迹"可以自动沿着你鼠标拖动的轨迹滑动 <!DOCTYPE html> <html lang="en"> ...

  6. JavaScript操作表格进行拖拽排序

    <js-dodo-table- Drag and Drop JQuery plugin > 以上插件可对table进行排序,拖动! 例如有下面一个样子的id为table的表格: <t ...

  7. javascript学习之模块拖拽功能的实现

  8. HTML5悬浮球源码,js拖拽360桌面悬浮球代码

    使用方法: 1.head引入css文件 * { margin: 0; padding: 0; list-style: none; } html, body { width: 100%; height: ...

  9. Nodejs express、html5实现拖拽上传(转载)

    一.前言 文件上传是一 个比较常见的功能,传统的选择方式的上传比较麻烦,需要先点击上传按钮,然后再找到文件的路径,然后上传.给用户体验带来很大问题.html5开始支持拖 拽上传的需要的api.node ...

最新文章

  1. 求最小Hamming距离的DNA序列
  2. 通过Matrix进行二维图形仿射变换
  3. 第一课 第四节 数据转换
  4. YII用户注冊和用户登录(五)之进行session和cookie分析 ,并在前后区分session和cookie...
  5. 提示MyEclipse Trial Expired,手动获取MyEclipse 注册码
  6. mysql怎么刷题_面试刷题mysql1:一条sql语句是如何经过mysql的体系结构的?
  7. 前端学习(2624):state
  8. 比尔•盖茨当选中国工程院外籍院士!(附名单)
  9. Java通过Mybatis实现批量插入数据到Oracle中
  10. Python一句话实现秦九韶算法快速计算多项式的值
  11. dhcp 配置及排错
  12. 【免费下载】2021年7月热门报告盘点(附热门报告列表及下载链接)
  13. [论文阅读] IL2M: Class Incremental Learning With Dual Memory
  14. pycharm编程工具自带python环境吗_pycharm+PyQt5+python最新开发环境配置(踩坑)
  15. 海思3519A配置IP
  16. 独家揭秘:用友云的新打算
  17. mysql安装包设置本地yum源安装包_mysql 5.7.29 在centos7.6下超简单的本地yum源安装与配置...
  18. Atitit 提升开发进度大方法--高频功能与步骤的优化 类似性能优化
  19. CONVERT TEXT(转换为可排序格式)
  20. SQL建表及插入数据

热门文章

  1. webservice接口--浅析一
  2. 泛型中的 T、E、K、V代表的意义
  3. STM32MP157驱动开发——Linux并发与竞争
  4. c# .net写一个监控电脑文件被动过痕迹的服务(开机自启)
  5. 商业图表案例9.1-蓝牙耳机续航时间对比
  6. python (建立文件)制作英文字典
  7. 2021重庆江北中学高考成绩查询,2020重庆各校高考成绩汇总
  8. TAEconomy-车辆动力性经济性模型库
  9. AfxMessageBox()函数消息框按钮和图标
  10. 关于web安全测试在功能测试中的应用