给力的 Google HTML5 训练营(HTML5 Drag&Drop 拖拽、FileReader实例教程)

2012-02-16 20:31

给力的 Google HTML5 训练营(HTML5 Drag&Drop 拖拽、FileReader实例教程)

by

at 2012-02-16 12:31:56

original http://item.feedsky.com/~feedsky/bingo929/~7170939/597761171/5279850/1/item.html

HTML5 Drag&Drop 、FileReader实例教程

  上周六有幸同我们人人网的几个同事一起去Google总部参加了《给力HTML5 —— 2011 Google HTML5 训练营》,从下午1点多到晚上9点多8个小时左右的时间,收获还是很大的,8个小时的时间把以前一直想学或想做的事情都给搞了一些。好久没有写博客了,今天也该分享些给力的东西了,正好借此次机会跟大家分享些HTML5相关的给力的技术(sessionStorage、localStorage、Web SQL DateBase、Indexed DB、Canvas绘图、FileReader、Drag&Drop…),何止是给力,简直就是给力!

您还可以参考以下HTML5相关文章:
HTML5 WebSockets 基础使用教程
关于HTML 5 canvas 的基础教程
让所有IE支持HTML5的解决方案
一起感受HTML5和CSS3的能量

Google HTML5 训练营

先简单介绍一下这个训练营的活动流程:
   1:00 – 1:30 注册
   1:30 – 2:30 HTML5 技术剖析
   技术讲座1 —— Google 工程师
   技术讲座2 —— 特邀嘉宾(李靖威、李继成,就职于人人网)
   2:30 – 3:00 宣布竞赛规则,开始组队
   3:00 – 6:30 作品创作 / 提交
   6:30 – 7:00 作品展示
   7:00 – 7:30 评奖、颁奖

  讲座部分,先是Google工程师寒蕊MM跟我们分享了些HTML5的新技术概况,其中大致包括:sessionStoragelocalStorageWeb SQL DateBaseIndexed DB,寒蕊MM还专门写了篇关于IndexedDB的文章《客户端数据存储》,文章用实例的方式讲了Web Storage(localStorage)、Web SQL Database 和 Indexed Database的用法。

  其中Web SQL Database虽是HTML5的技术,但由于某些原因,W3C组织(Web Applications Working Group)已不再维护这项技术,也就是说虽然目前Chrome、FireFox新版本浏览器支持这项技术,但不一定未来的版本还会支持。以下为w3c官网的声明:

Beware. This specification is no longer in active maintenance and the Web
Applications Working Group does not intend to maintain it further.

  Indexed DataBase最初是由Oracle提出的数据库API,没记错的话起初叫做Simple DataBase,之后演变成Indexed DataBase,而且已被Chrome和FireFox(版本4)所支持。

  这次活动规模比较小,由于人数限制在了30人,所以组队Coding阶段,每队5人,分成了6组~接下来就是短短3个小时左右的Coding了,我们人人网的四个人和另一位有Canvas经验的邱亮同学一起开发一个纯HTML5的可涂鸦日记本,其中有个插曲:一开始项目名字没多想就直接叫做《我的日记本》了,到最后提交项目的时候,Google MM说要起一个简洁且酷一些的名字,好吧,那我们就起一个简洁酷一些的名字,最后就叫《我日》!哇咔咔~让大家”贱笑”了~

html5-daily-book

  言归正传,《我日》项目之所以叫纯HTML5,其实只是使用了些HTML5技术,在短短的3个小时时间,从功能到分工开发,时间很紧~所以只是做了个小小的Demo版,基本功能实现的差不多了,但愿以后还能有时间把它完善一下~其中使用了这些HTML5技术:

  1.Web SQL DataBase :存取日记数据
  2.HTML5 Drag&Drop 事件 :监听网页内图片拖拽及本地图片直接拖拽到日记中的事件
  3.FileReader :获取本地图片拖拽到日记本里的图片数据
  4.Canvas :实现日记涂鸦功能(画笔、调色、文字、图片绘制到画布等…)
  5.HTML5新标签 :如:<input type=”range”… /> 、 <section> 、<article>等…
  6.CSS3

  今天我只详细讲讲我的分工部分:HTML5 Drag & Drop 和 FireReader这两个东西,以后有机会在和大家分享其他技术。

HTML5 Drag & Drop 事件

  过去我们想实现网页中的拖拽效果,基本上都是使用DOM事件模型中的mousedown、mousemove、mouseup的事件监听来模拟拖拽效果,为了实现实时的拖拽移动效果,还要不停地获取鼠标的坐标,还要不停的修改元素的位置,代码要堆很多,而且性能上也很不好(不停地修改元素位置会导致页面reflow,除非绝对定位),现在有了html5原生的Drag & Drop 拖拽事件,真的是方便了许多,用”事半功倍”来形容绝不为过。

Drag & Drop 包括以下事件

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

完成一次成功页面内元素拖拽的行为事件过程应该是: dragstart –> dragenter –> dragover –> drop –> dragend

Drag & Drop 网页内的元素拖拽:

  HTML5为元素新增了用于拖拽的属性draggable,这个属性决定了元素是否能被拖拽,如果draggable=”true”,则元素可被拖拽,否则只能选择元素的文本。

  值得一提的是HTML5支持拖拽数据存储,使用dataTransfer接口,作用于元素的拖拽基础上,dataTransfer对象包含以下属性和方法:

  • dataTransfer.dropEffect [ = value ]:返回已选择的拖放效果,如果该操作效果与起初设置的effectAllowed效果不符,则拖拽操作失败。可以设置修改,包含这几个值:“none”, “copy”, “link” 和 “move”
  • dataTransfer.effectAllowed [ = value ]:返回允许执行的拖拽操作效果,可以设置修改,包含这些值:“none”, “copy”, “copyLink”, “copyMove”, “link”, “linkMove”, “move”, “all” 和 “uninitialized”
  • dataTransfer.types:返回在dragstart事件出发时为元素存储数据的格式,如果是外部文件的拖拽,则返回”files”
  • dataTransfer.clearData ( [ format ] ):删除指定格式的数据,如果未指定格式,则删除当前元素的所有携带数据
  • dataTransfer.setData(format, data):为元素添加指定数据
  • dataTransfer.getData(format):返回指定数据,如果数据不存在,则返回空字符串
  • dataTransfer.files:如果是拖拽文件,则返回正在拖拽的文件列表FileList
  • dataTransfer.setDragImage(element, x, y):制定拖拽元素时跟随鼠标移动的图片,x、y分别是相对于鼠标的坐标(据测试,Chrome暂不支持)
  • dataTransfer.addElement(element):添加一起跟随拖拽的元素,如果你想让某个元素跟随被拖拽元素一同被拖拽,则使用此方法(据测试,Chrome暂不支持)

在dragstart事件触发时可以为被拖拽元素存储数据,就是使用上面说到的dataTransfer.setData,setData的数据格式一般有两种:”text/plain”(用于文本数据)和”text/uri-list”(用于url),你可以先为某个可拖拽元素设置微数据,然后为它设置draggable属性为true,之后在其dragstart事件触发时存储数据:
html部分:

<div id="dragMe" builddate="2011-1-10" draggable="true">拖拽我!</div>
<div id="dropHere"></div>

javascript部分:

var oDragMe = document.getElementById('dragMe');

oDragMe.addEventListener('dragstart', function(e) {
  e.dataTransfer.setData('text/plain', e.target.getAttribute('builddate'));
},false)

在拖拽结束的时候便可以获取相应元素的数据:

var oDropBox = document.getElementById('dropHere'),
  tmpData;

oDropBox .addEventListener('drop', function(e) {
  tmpData = e.dataTransfer.getData('text/plain');
},false)

创建拖拽事件监听的时候记得要把默认的行为事件去掉,毕竟浏览器是有默认拖拽行为的,尤其是dragover事件一定要使用e.preventDefault(),不然drop事件可能不会被触发:

oDropBox .addEventListener('dragover', function(e) {
  e.stopPropagation();
     e.preventDefault(<span style=