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

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

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

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

普通页面上我们按住鼠标可以选择上一段文字,而这个行为不同浏览器的发生阶段也不一样,有的是取消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

该例子是纵向拖动,横向是可以照常选择文字的。纵向拖动时也不会出现其它地方文字被选中的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jsPlumb提供了drag事件和stop事件来分别处理节点拖拽过程中和拖拽结束后的操作。 drag事件会在节点被拖拽的过程中被触发,可以通过它来实时获取节点的位置信息: ```js jsPlumb.bind("drag", function(element) { var pos = jsPlumb.getPosition(element.el); console.log(pos); }); ``` stop事件则会在节点拖拽结束后被触发,可以在该事件中进行一些后续处理,比如更新节点位置信息: ```js jsPlumb.bind("stop", function(element) { var pos = jsPlumb.getPosition(element.el); console.log(pos); // 更新节点位置信息 // ... }); ``` 完整代码示例: ```html <!DOCTYPE html> <html> <head> <title>jsPlumb节点拖拽释放事件</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jsPlumb/2.17.7/js/jsplumb.min.js"></script> <style type="text/css"> #container { width: 600px; height: 400px; border: 1px solid #ccc; position: relative; } .node { width: 100px; height: 100px; background-color: #f0f0f0; border: 1px solid #ccc; position: absolute; text-align: center; line-height: 100px; cursor: move; } </style> </head> <body> <div id="container"> <div class="node draggable" style="top: 100px; left: 100px;">节点1</div> <div class="node draggable" style="top: 200px; left: 200px;">节点2</div> </div> <script type="text/javascript"> jsPlumb.ready(function() { // 设置节点拖动 jsPlumb.draggable($(".draggable"), { containment: "parent" }); // 监听节点拖拽事件 jsPlumb.bind("drag", function(element) { var pos = jsPlumb.getPosition(element.el); console.log(pos); }); // 监听节点拖拽停止事件 jsPlumb.bind("stop", function(element) { var pos = jsPlumb.getPosition(element.el); console.log(pos); // 更新节点位置信息 // ... }); }); </script> </body> </html> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值