前言
我在之前写过关于 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 查看绑定的事件, 在平时的工作中, 切记不要污染全局的默认事件一般情况下, 工作中并不会遇到本文所说的这一情况, 但是如果真的碰到了, 需要知道问题的所在
来源: https://www.cnblogs.com/nzbin/p/8481241.html