您的位置:首页 > Web前端 > JavaScript

javascript节点拖动如何避免影响某些节点对象的默认行为【转自qiqiboy】

2013-07-01 23:46 267 查看
使用javascript开发可拖动组件时,往往需要对鼠标事件进行阻止默认行为操作。对于普通的节点对象,这个一般没什么问题(没有选择文字复制粘贴等需求),但是如果被拖动对象里包含了一些input、select等对象时,如果从一而终(mousestart ,mousemove,mouseend, click)全部preventDefault默认行为,则会使这些节点无法响应用户操作,比如聚焦input输入或者改变select的值。某些特殊情况下的需求(比如拖动是纵向单方向的,而另一方向横向上则需要可以用鼠标选择文字)更是一个不可能的任务。

进行拖动开发时,一般都是使用mousestart(鼠标按下)、mousemove(鼠标移动)、mouseend(鼠标抬起)这三个事件实现的,而click事件与这个事件也是有关系的,它是在mouseend后才会被触发的。

如果event.target是个链接,在经过前三个mouse事件后,click还是会,则会在拖动时看到图片或链接跟着鼠标有个拖影.所以在在此情况下,必须取消该默认行为. 如下图。




普通页面上我们按住鼠标可以选择上一段文字,而这个行为不同浏览器的发生阶段也不一样,有的是取消mousestart行为就不会选择了,而有的则是取消mousemove则不会选择,有的则需要同时取消mousestart和mousemove.

综上,我总结了一下各种情况,在自己的开发中应用了以下方法来兼容各个浏览器.

说明:以下例子均运行在标准浏览器环境. 对相关事件接口进行兼容,也是可以运行在ie等早期浏览器中的.

1: //首先定义一个后面会用到的函数

2: function returnFlase(evt){

3:     evt.preventDefault();

4: }


首先是对于mousestart(touchstart)

1: function mousestart(evt){

2:     var name=evt.target.nodeName.toLowerCase();

3:     if(evt.type!='touchstart' && ( //触摸设备上的浏览器就不需要了

4:         name=='a' ||

5:         name=='img' ||

6:     )) evt.preventDefault();

7:     this.removeEventListener('click',returnFalse,false); //取消 阻止默认行为

8: }


对于mousemove(touchmove)

在该事件中,最重要的是根据你的需求做出判断,比如是否锁定拖动方向、是否单方向拖动、是否有效拖动距离(ie下即使没有移动鼠标也有可能会触发mousemove)。如果用户确实执行了有效鼠标移动

1: function mousemove(evt){

2:     // ....

3:     if(move){

4:         evt.preventDefault();

5:         /* 这里是因为如果单方向拖动,会出现文字被选中的情况,这里需要去除文字选中效果 */

6:         if(window.getSelection!=null){//这里只需要考虑标准浏览器就行了,ie7 8下无此问题

7:             range=getSelection();

8:             if(range.empty)range.empty();

9:             else if(range.removeAllRanges)range.removeAllRanges();

10:         }

11:     }

12:     // ....

13: }


对于mouseend(touchend, touchcancel)

该事件中,重要的是判断用户是否是拖动后抬起的鼠标操作, 如果是的话,则需要阻止click事件. 与第一步中相呼应,第一步中我们需要removeEventListener这一步中添加的函数

1: function mouseend(){

2:     // ....

3:     if(move){

4:         /* 如果用户在第二步中有效拖动,则需要取消click事件的默认行为 */

5:         this.addEventListener('click',returnFalse,false);

6:     }

7:     // ....

8: }


如此以上处理后,拖动节点里的input select等都可以正常接收用户操作了。

说了不多也不少,没看懂就算了。我这里有个例子:http://u.boy.im/touchscroll/scroll.html

该例子是纵向拖动,横向是可以照常选择文字的。纵向拖动时也不会出现其它地方文字被选中的情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息