JavaScript 拖放效果.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《JavaScript 拖放效果.pdf》由会员分享,可在线阅读,更多相关《JavaScript 拖放效果.pdf(19页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、JavaScript 拖放效果拖放效果,也叫拖拽、拖动,学名Drag-and-drop,是最常见的 js 特效之一。如果忽略很多细节,实现起来很简单,但往往细节才是难点所在。这个程序的原型是在做图片切割效果的时候做出来的,那时参考了好几个同类的效果,跟 muxrwc 和 BlueDestiny 学习了不少东西。虽然每次整理都觉得很好了,不过每隔一段时间又会发现得某个地方可以改善,某个地方有错误,某些需求需要实现,就像自己学习的知识那样。这里考虑到有的人可能只需要简单的拖放,所以有一个简化版的拖放 SimpleDrag,方便学习。效果预览在 maxthon 下如果开启广告过滤的话很可能会被过滤掉
2、(不知有什么方法可以避免)。拖放状态:结束拖放程序说明【程序原理】这里以 SimpleDrag 为例说一下基本原理。首先初始化程序中要一个拖放对象:this.Drag=$(drag);还要两个参数在开始时记录鼠标相对拖放对象的坐标:this._x=this._y=0;还有两个事件对象函数用于添加移除事件:this._fM=BindAsEventListener(this,this.Move);this._fS=Bind(this,this.Stop);分别是拖动程序和停止拖动程序。拖放对象的 position 必须是 absolute 绝对定位:this.Drag.style.position
3、=absolute;最后把 Start 开始拖放程序绑定到拖放对象 mousedown 事件:addEventHandler(this.Drag,mousedown,BindAsEventListener(this,this.Start);鼠标在拖放对象按住,就会触发 Start 程序,主要是用来准备拖动,在这里记录鼠标相对拖放对象的坐标:this._x=oEvent.clientX-this.Drag.offsetLeft;this._y=oEvent.clientY-this.Drag.offsetTop;并把_fM拖动程序和_fS停止拖动程序分别绑定到document的 mousemov
4、e 和 mouseup 事件:addEventHandler(document,mousemove,this._fM);addEventHandler(document,mouseup,this._fS);绑定到 document 可以保证事件在整个窗口文档中都有效。当鼠标在文档上移动时,就会触发 Move 程序了,这里就是实现拖动的程序。通过现在鼠标的坐标值跟开始拖动时鼠标相对的坐标值的差就可以得到拖放对象应该设置的 left 和 top 了:this.Drag.style.left=oEvent.clientX-this._x+px;this.Drag.style.top=oEvent.c
5、lientY-this._y+px;最后放开鼠标后就触发 Stop 程序结束拖放。这里的主要作用是把 Start 程序中给 document 添加的事件移除:removeEventHandler(document,mousemove,this._fM);removeEventHandler(document,mouseup,this._fS);这样一个简单的拖放程序就做好了,下面说说其他扩展和细节部分。【拖放锁定】锁定分三种,分别是:水平方向锁定(LockX)、垂直方向锁定(LockY)、完全锁定(Lock)。这个比较简单,水平和垂直方向的锁定只要在 Move 判断是否锁定再设置left和to
6、p就行,如果是完全锁定就直接返回。if(!this.LockX)this.Drag.style.left=;if(!this.LockY)this.Drag.style.top=;【触发对象】触发对象是用来触发拖放程序的,程序中通过 Handle 属性设置。有的时候不需要整个拖放对象都用来触发,这时就需要触发对象了。使用了触发对象后,进行移动的还是拖放对象,只是用触发对象来触发拖放(一般的使用是把触发对象放到拖放对象里面)。ps:触发对象的另一个用法是通过设置相同的 Handle,实现一个触发对象同时拖放多个拖放对象。【范围限制】要设置范围限制必须先把 Limit 设为 true。范围限制分两
7、种,分别是固定范围和容器范围限制,主要在 Move 程序中设置。原理是当比较的值超过范围时,修正 left 和 top 要设置的值使拖放对象能保持在设置的范围内。【固定范围限制】容器范围限制就是指定上下左右的拖放范围。各个属性的意思是:上(mxTop):top 限制;下(mxBottom):top+offsetHeight 限制;左(mxLeft):left 限制;右(mxRight):left+offsetWidth 限制。如果范围设置不正确,可能导致上下或左右同时超过范围的情况,程序中有一个 Repair 程序用来修正范围参数的。Repair 程序会在程序初始化和 Start 程序中执行,
8、在 Repair程序中修正 mxRight 和 mxBottom:this.mxRight=Math.max(this.mxRight,this.mxLeft+this.Drag.offsetWidth);this.mxBottom=Math.max(this.mxBottom,this.mxTop+this.Drag.offsetHeight);其中 mxLeft+offsetWidth 和 mxTop+offsetHeight 分别是mxRight 和 mxBottom 的最小范围值。根据范围参数修正移动参数:iLeft=Math.max(Math.min(iLeft,mxRight-th
9、is.Drag.offsetWidth),mxLeft);iTop=Math.max(Math.min(iTop,mxBottom-this.Drag.offsetHeight),mxTop);对于左边上边要取更大的值,对于右边下面就要取更小的值。【容器范围限制】容器范围限制的意思就是把范围限制在一个容器_mxContainer 内。要注意的是拖放对象必须包含在_mxContainer 中,因为程序中是使用相对定位来设置容器范围限制的(如果是在容器外就要用绝对定位,这样处理就比较麻烦了),还有就是容器空间要比拖放对象大,这个就不用说明了吧。原理跟固定范围限制差不多,只是范围参数是根据容器的属性
10、的设置的。当设置了容器,在Repair程序会自动把position设为relative来相对定位:!this._mxContainer|CurrentStyle(this._mxContainer).position=relative|(this._mxContainer.style.position=relative);ps:其中CurrentStyle 是用来获取最终样式(详细看这里的最终样式部分)。注意如果在程序执行之前设置过拖放对象的 left 和 top 而容器没有设置 relative,在自动设置 relative时会发生移位现象,所以程序在初始化时就执行一次 Repair程序防止
11、这种情况。因为 offsetLeft 和 offsetTop 要在设置relative 之前获取才能正确获取值,所以在 Start 程序中Repair 要在设置_x 和_y 之前执行。由于是相对定位,对于容器范围来说范围参数上下左右的值分别是 0、clientHeight、0、clientWidth。clientWidth 和 clientHeight 是容器可视部分的宽度和高度(详细参考这里)。为了容器范围能兼容固定范围的参数,程序中会获取容器范围和固定范围中范围更小的值:Code因为设置相对定位的关系,容器_mxContainer 设置过后一般不要取消或修改,否则很容易造成移位异常。【鼠标
12、捕获】我在一个拖放实例中看到,即使鼠标移动到浏览器外面,拖放程序依然能够执行,仔细查看后发现是用了 setCapture。鼠标捕获(setCapture)是这个程序的重点,作用是将鼠标事件捕获到当前文档的指定的对象。这个对象会为当前应用程序或整个系统接收所有鼠标事件。使用很简单:this._Handle.setCapture();setCapture 捕获以下鼠标事件:onmousedown、onmouseup、onmousemove、onclick、ondblclick、onmouseover 和onmouseout。程序中主要是要捕获 onmousemove 和 onmouseup 事件。
13、msdn 的介绍中还说到 setCapture 有一个 bool 参数,用来设置在容器内的鼠标事件是否都被容器捕获。容器就是指调用 setCapture 的对象,大概意思就是:参数为 true 时(默认)容器会捕获容器内所有对象的鼠标事件,即容器内的对象不会触发鼠标事件(跟容器外的对象一样);参数为 false 时容器不会捕获容器内对象的鼠标事件,即容器内的对象可以正常地触发事件和取消冒泡。而对于容器外的鼠标事件无论参数是什么都会被捕获,可以用下面这个简单的例子测试一下(ie):Code这里的参数是 true,一开始 body 会捕获所有鼠标事件,即使鼠标经过 div 也不会触发 onmous
14、emove 事件。换成 false 的话,div 就可以捕获鼠标事件,就能触发 div 的onmousemove 事件了。拖放结束后还要使用 releaseCapture 释放鼠标,这个可以放在 Stop 程序中:this._Handle.releaseCapture();setCapture 是 ie 的鼠标捕获方法,对于 ff 也有对应的captureEvents 和 releaseEvents 方法。但这两个方法只能由 window 来调用,而且 muxrwc 说这两个方法在 DOM2 里已经废弃了,在 ff 里已经没用了。不过 ff 里貌似会自动设置取消鼠标捕获,但具体的情形就不清楚了
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JavaScript 拖放效果 拖放 效果
![提示](https://www.deliwenku.com/images/bang_tan.gif)
限制150内