关于 JS 拖拽功能的冲突问题及解决方法
前言
我在之前写过关于 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 查看绑定的事件,在平时的工作中,切记不要污染全局的默认事件。一般情况下,工作中并不会遇到本文所说的这一情况,但是如果真的碰到了,需要知道问题的所在。
关于 JS 拖拽功能的冲突问题及解决方法的更多相关文章
- 原生js拖拽功能制作滑动条实例教程
拖拽属于前端常见的功能,很多效果都会用到js的拖拽功能.滑动条的核心功能也就是使用js拖拽滑块来修改位置.一个完整的滑动条包括 滑动条.滑动痕迹.滑块.文本 等元素,先把html代码写出来,如下所示: ...
- 关于js拖拽功能,拖拽元素的position:fixed;left:0;right:0;样式引起左右拖动元素会出现落后鼠标移动距离的问题
被拖拽元素的样式如果为:position:fixed;left:0;right:0;(当时是为了让fixed定位的元素水平居中加的left:0;right:0;避免js动态计算定位的麻烦)时左右拖动会 ...
- chrome无法拖拽离线安装CRX格式插件解决方法
原文:http://chromecj.com/utilities/2018-09/1525.html 摘要 : chrome 67版本后无法拖拽离线安装CRX格式插件的解决方法 有一部分网友反映子 ...
- 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...
- Js元素拖拽功能实现
Js元素拖拽功能实现 需要解决的问题 最近项目遇到了一个问题,就是用户某个操作需要弹出一个自定义的内容输入框,但是有个缺点,当浏览太大的时候没办法点击确认和取消按钮,应为这个弹出框是采用绝对定位的,取 ...
- vuejs2.0使用Sortable.js实现的拖拽功能
简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...
- vue2.0使用Sortable.js实现的拖拽功能
简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jQuery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...
- js进阶 12-17 jquery实现鼠标左键按下拖拽功能
js进阶 12-17 jquery实现鼠标左键按下拖拽功能 一.总结 一句话总结:监听的对象必须是文档,鼠标按下运行mousemove事件,鼠标松开取消mousemove事件的绑定,div的偏移的话是 ...
- (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
利用JavaScript(JS)实现一个九宫格拖拽功能 Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...
随机推荐
- 微调数据库表结构,30 分钟搞定 WordPress 数据库查询缓慢问题
同事的美女图片站,基于 WordPress 搭建的,因为数据越来越多,变得慢,我从 PHP slow log 里面看出是 WordPress 有些查询总是很慢,即使已经安装了页面缓存插件,但是由于页面 ...
- hashCode方法和equals方法比较
为什么用HashCode比较比用equals方法比较要快呢?我们要想比较hashCode与equals的性能,得先了解HashCode是什么. HashCode HashCode是jdk根据对象的地址 ...
- linux_nginx_rewrite
什么是Nginx的rewrite? 实现URL地址重写,比较复杂的write需要开发来完成,伪静态处理实现是开发的工作, 这rewrite写在location中 指令语法: rewrite re ...
- jinja2.exceptions.TemplateNotFound: home/index.html
问题: 检查路由路径和模版渲染方式,其他文件路径都正确,可以返回字符串,就是无法返回定义的模版,为什么flask无法启找到这个模版? 那,问题原因在哪? 在flask中,目录有着严格的定义,模版目录必 ...
- 爬虫_网页url设计
为什么需要网页URL设计? 每个url不同的结构代表着不同的网页模块和信息的展现形式,为了方便维护与管理 网页url怎么设计? 分层: 主域名,子域名 一般形式为: 主域名: www.job.com ...
- python_协程方式操作数据库
# !/usr/bin/python3 # -*- coding: utf-8 -*- import requests import gevent import pymysql from gevent ...
- Linux平台ORACLE INSTANT客户端安装
下载安装文件 先去ORACLE官方网站下载所需版本的Instant Client Package 和 Instant Client Package - SQL*Plus安装包,(千万注意版本) htt ...
- zabbix监控windows agent安装配置
下载Windows的zabbix客户端 下载地址:http://www.zabbix.com/download.php 从官方下载Zabbix Agent后,压缩包里面有2个目录,bin和conf,c ...
- python --- mulitprocessing(多进程)模块使用
1. 什么是进程? 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执 ...
- Date对象和正则对象
1.Date对象 创建 var date1 = new Date(); var date2 = new Date(12983798123);//填一个毫秒值,应该是距离1970年1月1日.....多少 ...