Pro JavaScript (12)

January 20, 2006 at 4:46 am | Posted in JavaScript | 1 Comment

Pro JavaScript (12) 鼠标拖放

—————————————————————————————————————————

能实现鼠标拖放当然很好,例如IE的实现方法就不错,简单易用,但是只适用于IE,对于其他浏览器则,由于不支持拖拽的时间,需要我们自己去定义方法,使用mouse的低级事件来进行模拟。UGLY也没有办法,目前漂亮的实现拖放功能的是google的个性化主页netvibes

简单介绍一下IE的方式

IE建立了完善的Drag-Drop事件机制:

当某Dragable对象被drag时,事件激发属性是:dragstart->drag(一直持续)->dragend(停止) ,注意这些事件针对被Drag的对象。

对于Drag的目标对象,当被拽对象进入目标时候,dragenter被激发,然后只要被拽对象还在目标范围内,dragover就会一直继续激发(同时drag事件也会持续激发),这时如果放下/drop,则drop事件被激发,如果没有放下,而被拽离目标对象时则dragleave被激发。

对于默认本来不是合法的目标对象,可以通过改变dragenterdragover的默认属性来使之成为合法的目标。

IE5.0以后,可以通过dataTransfer来进行拖拽对象的数据传递。

该对象除了setter/getter之外还有两个重要的属性:针对拖拽对象的effectAlloweduninitiallized /none/copy/link/move/copyLink/copyMove/linkMove/all)和针对目标对象的dropEffect none/move/copy/link

另外,对于IE5.5以上,基本上对于所有的HTML元素,都可以使用dragDrop()方法使得本来不是拖拽对象的元素可以变为可拖拽对象(即可以激发dragstart, drag, dragend事件)

通用浏览器的方式:

可惜的是,没有很好的跨浏览器解决办法,(DOM3遥遥无期,XUL只适用于Mozilla),只能采取模拟的方式。思路是利用鼠标事件的低级方法,以及事件的鼠标位置和Divstyle方法,来控制Div的位置。也就是在oDiv.style.left/oDiv.style.topoEvent.clinetX/oEvent.clinetY上做文章。以及运用oDiv.offsetXXX诸方法。


让一个Div跟随鼠标移动,首先定位出初始时(即mousedown事件)鼠标初始点(clientX/Y)与div左上角(offsetLeftoffsetTop)之间的距离。

然后当鼠标移动时(mousemove事件),把div的位置(style.left/style.top)置为鼠标当前点(clientX/Y)与前面初始时获得的距离(DiffX/Y)之差。


Netvibesgoogle)的Drag.js

预备知识:JSONJavaScriptiterals

ECMAScript v3规范中,变量可以直接为作为对象字面量(object literal) 如:

Var foo ={ x:1, y:2 } // An object initializer

object literalsJavaScript 1.2 就被支持,但直到ECMAScript v3才成为标准。,JSON,使用了这种对象定义方法,JSON主要的好处时可以把对象通过纯文本来传递(好像XML),但是不需要XML parser,直接使用JavaScriptevel语句,客户端就可以得到对象

参考:

http://www.crockford.com/JSON/index.html

http://developer.yahoo.net/common/json.html

http://www.quirksmode.org/blog/archives/2005/12/the_ajax_respon.html


netvibes的拖拽界面实现的很不错,它和google的个性化主页实现的原理是一样的。其中实现DragDorp功能的主要是由Drag.jshttp://www.netvibes.com/js/Drag.js)。

拖拽divModuleHeader时,首先mousedown事件被触发调用Drag.startDrag.start 会调用divMoudleonDragStart方法,并设置mousemove/moseup事件的处理函数。

然后mousemove事件触发Drag.drag,它会调用divModuleonDrag方法

然后mouseup事件触发Drag.end,它会调用divModuleonDragEnd方法

divMoudle的几个方法onDragStartonDragonDragEnd,主要为了解决divMoudleGhost(指divMoudle下面红色的虚线标示框)的创建,在页面中的位置,移动。

Advertisements

1 Comment »

RSS feed for comments on this post. TrackBack URI

  1. Here are some links that I believe will be interested


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: