首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于 JS 拖拽功能的冲突问题及解决方法

关于 JS 拖拽功能的冲突问题及解决方法

作者头像
叙帝利
发布2018-03-28 13:10:17
2.3K0
发布2018-03-28 13:10:17
举报
文章被收录于专栏:前端新视界前端新视界

前言

我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考。本文主要介绍解决这种冲突的方法,其实就是事件绑定的时机问题。

问题来源

这个问题是在类似如下 CodePen 例子中发现的,在有拖拽功能的页面中添加一个原生 input range 元素,可以发现 input range 的拖拽失效了。

See the Pen drag with conflict issue by Zongbin (@nzbin) on CodePen.

让我们看一下拖拽方法代码:

var draggable = function(modal, handle) {
...
  $(handle).on('mousedown', dragStart);
  $(document).on('mousemove', dragMove);
  $(document).on('mouseup', dragEnd);
}

几乎网上的大部分拖拽案例都是上面这种绑定事件的方法。起初以为是 jQuery 事件绑定的问题,其实完全不相关,使用原生 JS 同样会遇到这种问题。

再看一下拖拽的事件绑定,很明显,在 document 上绑定的事件和 input range 的拖拽事件冲突了。其实,document 作为最上层的节点,它上面不应该绑定其它事件(事件代理除外),如果绑定,必须是临时性绑定,否则一定会造成冲突。

解决方法

知道问题所在之后,解决方法也非常简单,其中参考了 jQuery UI 的处理方式。

我们可以在拖拽开始的时候绑定 document 的事件,然后在拖拽结束的时候移除 document 的事件。

var draggable = function(modal, handle) {
...
  var dragStart = function(e) {
...
    $(document).on('mousemove', dragMove)
               .on('mouseup', dragEnd);
  }
...

  var dragEnd = function(e) {
    $(document).off('mousemove')
               .off('mouseup');
...
  }

  $(handle).on('mousedown', dragStart);
  
}

下面 CodePen 中的 input range 已经可以正常拖动了。

See the Pen drag with conflict issue fixed by Zongbin (@nzbin) on CodePen.

总结

我们可以通过控制台的 Event Listener 查看绑定的事件,在平时的工作中,切记不要污染全局的默认事件。一般情况下,工作中并不会遇到本文所说的这一情况,但是如果真的碰到了,需要知道问题的所在。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 问题来源
  • 解决方法
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档