http://www.iteye.com/topic/1123335
原文地址:http://www.cnblogs.com/xueduanyang/archive/2012/05/03/2480505.html 上一篇,我们了解了KitJs的基本的事件管理架构,在kit.js核心的js包里面通过自己的事件匿名函数来托管用户注册时间,实现事件的执行顺序以及保存事件句柄。 今天我们来了解下Kit是如何实现拖拽事件的,Demo地址:http://xueduany.github.com/KitJs/KitJs/demo/Puzzle/demo.html KitJs官网:http://xueduany.github.com/KitJs Source Code:https://github.com/xueduany/KitJs (一)独立的Event.js不同于上一篇介绍的两个事件方法ev和delEv,对于增强型事件,即可能是浏览器自带的,但是存在复杂的兼容问题,或者是浏览器不带的,需要多次复合运算才能实现的事件,比如鼠标手势,画圈等等,kit统一使用Event.js进行管理。 Event.js的API DOC:http://xueduany.github.com/jsdoc/out/$Kit.Event.html 基本的事件注册机制是和上一篇介绍的完全一样,我们只是在浏览器兼容以及Event Object增强上做了手脚。 (二)原生的Drag/Drop事件我们都知道目前市面上很多很多的js框架都是通过mousemove模拟的方式,判断拖拽元素的offset与目标元素的offset来实现拖拽。其主要原因是IE对于drag/drop的不支持,其实事实的真相真的是这样的吗? 我们可以看到微软自己的API DOC:http://msdn.microsoft.com/en-us/library/ie/ms536923(v=vs.85).aspx 他提供了详细的支持drag事件的元素列表
可惜MSDN给出的文档上,只给了文字和form元素的例子,我们很多时候需要拖拽的是一个div Block元素,肿么办? dottora给出了这个API:http://help.dottoro.com/ljmojcxu.php 结合我给出的这个例子: http://xueduany.github.com/KitJs/KitJs/demo/DragDrop/demo.html 我们可以发现,IE也是支持Bloack元素的拖拽的 秘密在哪儿呢? (三)IE原生拖拽Block元素的秘密查看Kit源代码,我们可以发现
Event.js里面,对于IE如果绑定的是drag类的事件,他做了两件事 1. 注册一个mousedown事件 2. 在mousedown事件里面执行元素的dragDrop方法 这两件事情很有意思,这样你就会惊喜的发现,在IE里面,原来不能拖动的block元素可以拖动了。一切就是这么的神奇。 (四)HTML5 Support浏览器的拖拽相对于IE来说,其他的浏览器就显得简单了,只要支持HTML5的浏览器,我们只需要 设置元素的draggable属性为true即可拖动。 (五)Drop事件drop事件需要注意的是,必须要取消drop目标的dragOver默认事件,否则目标的drop事件不会触发,就像这样,全浏览器皆如此 (六)原生的Drop事件没有dragElement,肿么办?以上的代码已经搞定了IE+高级浏览器的dragDrop事件了,现在唯一的问题就是 1. drag和drop是在不同元素上注册的事件,drag注册在拖动目标上,drop注册在需要drop的目标上。所以产生的EventObject不相同 2. 原生的drop事件,没有dragElement,他是通过事件的dataTranfer成员传递对象的,而dataTransfer成员是个剪贴板,只能保存String 所以肿么办?肿么办? 别急,如果你好好的看懂了我们上一篇介绍的KitJs高级事件管理的话,你一定会想到我们说的Event Object增强。 对,KitJs就是这么做的! 由于Js是单线程的,所以同一时间触发的drag事件,只有一个dragElement,利用这个特性,KitJs决定把这个dragElement引用保存在Event.js的实例中 上图的代码中,Kit注册了dragStart事件,将当前拖拽的元素,保存在Kit.Event实例kit.event里面
回顾上一篇,我们介绍了Kit的ev方法里面,会在托管事件的匿名函数中,给当前的EventObject合并一些额外的数据,来增强事件 Kit.Event 采用同样的原理,而且KitEvent需要合并的数据更多,更可控,它自己保存了一个Event Object增强信息的数组,叫做eventExtraInfoFnArray,数组里面可以存放Function以及Map类型,用户可以通过暴露接口 让用户自己选择给EventObject增强哪些数据,如果是Map,就直接mergeIf,如果是Function,就传入当前 EventObejct,并执行Function,将返回值mergeIf *Kit.Event重构了evExtra方法,原来在kit.js里面事件托管匿名函数中,用来增强Event Object,插入一些我们需要的额外信息的方法
因为dragDrop的执行顺序是drag->drop 所 有只要有drag事件,触发,当前的dragElement就被保存在KitEvent实例中,这样到drop事件时,由于evExtra方法的缘 故,KitEvent中的dragElement就被插入到drop事件的EventObject里面,这样在drop事件,既可以取到当前拖拽的元素 了。 (当然,有人会问,按照这样的说法,kitEvent的dragElement岂不是一直被覆盖吗?就算没有发生drag事件,或者drag事件已经结束了,KitEvent的dragElement还存在吗?) Kit会自己注册一个dragEnd事件,用于清除KitEvent的dragEleemnt以及相关的extraEventInfo (七)draggable拖拽移动Kit通过注册dragStart事件,保存拖拽刚开始时候,拖拽元素的坐标信息 注册drag事件,获取鼠标移动的位移信息,根据之前的初始信息,移动元素的位置,实现拖拽 Demo:http://xueduany.github.com/KitJs/KitJs/demo/Dialog/demo.html 这里由于Firefox浏览器一向的垃圾以及BUG满天飞,Kit暂时无法获取FF下drag事件的鼠标移动数据,只有当dragEnd时,才能移动元素,敬请原谅。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
返回顶楼 | |
发表时间:2012-05-03 最后修改:2012-05-03
楼主的分享很有价值,楼主辛苦了。
至于说“Firefox浏览器一向的垃圾以及BUG满天飞”我就不敢苟同了,在我看来,Firefox才是bug最少的浏览器,Chrome简直就是个半成品,Safari连半成品都算不上。 firefox下无法获取drag事件的鼠标位置,这个bug是真的: https://bugzilla.mozilla.org/show_bug.cgi?id=590355 Bug 590355 - "drag"-event not containing mouse position 悲剧的是,在Firefox 12还没有修复。 |
|
返回顶楼 | |
发表时间:2012-05-03 最后修改:2012-05-03
cuixiping 写道
楼主的分享很有价值,楼主辛苦了。
至于说“Firefox浏览器一向的垃圾以及BUG满天飞”我就不敢苟同了,在我看来,Firefox才是bug最少的浏览器,Chrome简直就是个半成品,Safari连半成品都算不上。 firefox下无法获取drag事件的鼠标位置,这个bug是真的: https://bugzilla.mozilla.org/show_bug.cgi?id=590355 Bug 590355 - "drag"-event not containing mouse position 悲剧的是,在Firefox 12还没有修复。 楼上是道友,呵呵,幸会,说实话,我以前觉得FF很好的,妈的现在到处搞自己的私有方法,BUG一大堆也不修理,迟早和IE6一样烂 Chrome也很烂,尤其是android开发时候,但是bug确实相对于FF少点,就我遇到的 Safari这玩意真的是chrome核心的吗?我严重怀疑!!! 哎,前端真不好混 |
|
返回顶楼 | |
发表时间:2012-05-03
xueduanyang 写道
cuixiping 写道
楼主的分享很有价值,楼主辛苦了。
至于说“Firefox浏览器一向的垃圾以及BUG满天飞”我就不敢苟同了,在我看来,Firefox才是bug最少的浏览器,Chrome简直就是个半成品,Safari连半成品都算不上。 firefox下无法获取drag事件的鼠标位置,这个bug是真的: https://bugzilla.mozilla.org/show_bug.cgi?id=590355 Bug 590355 - "drag"-event not containing mouse position 悲剧的是,在Firefox 12还没有修复。 楼上是道友,呵呵,幸会,说实话,我以前觉得FF很好的,妈的现在到处搞自己的私有方法,BUG一大堆也不修理,迟早和IE6一样烂 Chrome也很烂,尤其是android开发时候,但是bug确实相对于FF少点,就我遇到的 Safari这玩意真的是chrome核心的吗?我严重怀疑!!! 哎,前端真不好混 私有方法大家都有一大堆,现在版本的firefox已经大部分标准化了,但chrome的私有方法还非常 多,你在console输入webkit,看到一大堆的列表……,在到firefox的console里输入moz,列表是不是短了很多?我 firefox12,Chrome19. 其实应该说是Gecko vs Webkit,不抠那个字眼了。 有些技术,chrome根本就不支持或者bug严重,比如MathML(Chrome不支持), SVG(chrome下的svg bug比其他任何现代浏览器都多) 看官方英文站的技术说明,就能发现很多。 |