通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
前言
关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球。本文的重点是讲解如何在某些特定的元素上禁止拖拽。这是我在编写插件时遇到的问题,其实很多插件的拖拽功能并没有处理这些细节,经过翻阅 jquery ui 的源码才找到答案。
拖拽实现
关于拖拽功能不再啰嗦,直接贴代码
/**
* [draggable 拖拽方法]
* @param {[type]} modal [移动元素]
* @param {[type]} handle [拖拽元素]
*/
var draggable = function(modal, handle) { var isDragging = false; var startX = 0,
startY = 0, left = 0,
top = 0; var dragStart = function(e) { var e = e || window.event; e.preventDefault(); isDragging = true; startX = e.clientX;
startY = e.clientY; left = $(modal).offset().left;
top = $(modal).offset().top; } var dragMove = function(e) { var e = e || window.event; e.preventDefault(); if (isDragging) { var endX = e.clientX,
endY = e.clientY, relativeX = endX - startX,
relativeY = endY - startY; $(modal).css({
left: relativeX + left + 'px',
top: relativeY + top + 'px'
}); } return false; } var dragEnd = function(e) { isDragging = false; } $(handle).on('mousedown', dragStart); $(document).on('mousemove', dragMove); $(document).on('mouseup', dragEnd);
}
使用方法
演示 Demo HTML
<div class="modal" id="modal">
<div class="modal-header">
<button class="btn-close"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body"></div>
</div>
演示 Demo CSS
.modal {
position: fixed;
top: 100px;
left: 100px;
width: 300px;
border: 1px solid #aaa;
padding: 3px;
border-radius: 5px;
}
.modal-header {
height: 24px;
line-height: 24px;
background-color: #ddd;
color: #222;
padding: 5px;
border-radius: 3px;
}
.modal-body {
height: 100px;
}
.btn-close {
width: 24px;
height: 24px;
float: right;
padding: 3px;
}
演示 Demo JS
draggable('#modal', '#modal .modal-header');
我们可以通过第二个参数指定不同的拖拽元素,比如可以指定整个 modal 为拖拽元素
draggable('#modal','#modal');
拖拽问题
整个拖拽功能并没有太大的问题,但是如果我们拖拽关闭按钮,仍然可以拖拽整个 modal,看起来不太和谐而且在某些情况下会影响功能,所以我们需要排除掉关闭按钮。

排除特定元素的方法
关于如何排除特定元素的方法,很多人会推荐阻止冒泡的方法,但是我试了很多次,这种方法是不行的,因为拖拽事件绑定在了 document 对象上。解决的方法就是在拖拽开始时添加限制条件,代码如下
...
var dragStart = function(e) { var e = e || window.event; e.preventDefault(); // 获取需要排除的元素
var elemCancel = $(e.target).closest(element);
// 如果拖拽的是排除元素,函数返回
if (elemCancel.length) {
return true;
} isDragging = true; startX = e.clientX;
startY = e.clientY; left = $(modal).offset().left;
top = $(modal).offset().top; }
...
为什么使用 closest() 方法呢?因为我们在排除特定元素的同时也要排除它的子元素。如果使用原生 JS 的话,需要添加获取子元素的方法。以下是完整代码:
/**
* [draggable 拖拽方法]
* @param {[type]} modal [移动元素]
* @param {[type]} handle [拖拽元素]
* @param {[type]} cancle [排除元素]
*/
var draggable = function(modal, handle, cancle) { var isDragging = false; var startX = 0,
startY = 0, left = 0,
top = 0; var dragStart = function(e) { var e = e || window.event; e.preventDefault(); // 获取需要排除的元素
var elemCancel = $(e.target).closest(cancle);
// 如果拖拽的是排除元素,函数返回
if (elemCancel.length) {
return true;
} isDragging = true; startX = e.clientX;
startY = e.clientY; left = $(modal).offset().left;
top = $(modal).offset().top; } var dragMove = function(e) { var e = e || window.event; e.preventDefault(); if (isDragging) { var endX = e.clientX,
endY = e.clientY, relativeX = endX - startX,
relativeY = endY - startY; $(modal).css({
left: relativeX + left + 'px',
top: relativeY + top + 'px'
}); } return false; } var dragEnd = function(e) { isDragging = false; } $(handle).on('mousedown', dragStart); $(document).on('mousemove', dragMove); $(document).on('mouseup', dragEnd);
}
上面的案例的 JS 修改如下:
draggable('#modal','#modal .modal-header', '#modal .btn-close');

总结
其实这个拖拽案例算是 jquery ui 拖拽功能的简单实现。仍然是之前的老话,实现一个功能并不困难,但是如果要把这个功能做好,我们需要考虑很多的细节,或许很多时候我们都把时间花费在调整细节上了。
通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽的更多相关文章
- 非node环境下的vue.js 实现简单的购物车计算功能 样式请无视
都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用.自己的实现如下: <!DOCTYPE html> <html lang="en"> &l ...
- (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
利用JavaScript(JS)实现一个九宫格拖拽功能 Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...
- JQuery UI的拖拽功能
JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...
- JQuery UI的拖拽功能实现方法小结
JQuery UI提供的API极大简化了拖拽功能的开发.只需要分别在拖拽源(source)和目标(target)上调用draggable和droppable两个函数即可. 拖拽原理 首先要明确几个概念 ...
- duilib中控件拖拽功能的实现方法(附源码)
转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...
- Atitit。D&D drag&drop拖拽功能c#.net java swing的对比与实现总结
Atitit.D&D drag&drop拖拽功能c#.net java swing的对比与实现总结 1. 实现一个D&D操作一般包括三个步骤: 1 2. .net黑头的拖曳机制 ...
- JS实现简单的运行代码 & 侧边广告
/* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...
- 关于 JS 拖拽功能的冲突问题及解决方法
前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...
- js进阶 12-17 jquery实现鼠标左键按下拖拽功能
js进阶 12-17 jquery实现鼠标左键按下拖拽功能 一.总结 一句话总结:监听的对象必须是文档,鼠标按下运行mousemove事件,鼠标松开取消mousemove事件的绑定,div的偏移的话是 ...
随机推荐
- ORACLE 错误代码提示归集
有时数据库出现问题,不是每次都有网络可查,所以把所有的ora系列的错误整理出来, 在最没有办法的时候,需要自己来解决,有了这些根据,问题会好办的.虽说对于数据库方面, DBA很强大,他们在遇到错误时, ...
- C语言之for循环
#include<stdio.h>#include<stdlib.h>#include<time.h>int main(){ int i; for(i=1;i< ...
- Java(概略篇)
准备 下载并安装Java jdk 和 编辑器(eclipse或Netbeans) 配置环境变量 第一个程序 public class test{ public static void main(Str ...
- log4net使用注意事项
1配置Log4net Log4net的配置文件有几种使用方式,这里将配置log4net的部分独立出来,即关于log4net的配置独立成文件log4net.config. 1)写入Mysql log4n ...
- HDU-1242-Rescu
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- JS 判断某个字符串是否存在与数组中
<script> function in_array(stringToSearch, arrayToSearch) { for (s = 0; s < arrayToSearch.l ...
- LNMP1.3 一键配置环境,简单方便
系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要3GB以上硬盘剩余空间 需要128MB以上内存(如果为128MB的小内存VPS,Xe ...
- Java SE 8 流库(二)
1.3. filter,map,flatMAP方法 流的转换会产生一个新流,它的元素派生出自另一个流中的元素: Stream<T> filter(Predicate<? super ...
- 【本地资源路径&&网络资源路径&&正反斜杠在Java中的用法】
一.概念和用法 左正右反 先来看看转义字符的概念:通过 \ ,?来转变后面字母或符号的含义.意思就是改变字母本身的含义. 以"\"符号为例,JAVA中有很多操作,例如文件操作等,需 ...
- MySQL系列:高可用架构之MHA
前言 从11年毕业到现在,工作也好些年头,入坑mysql也有近四年的时间,也捣鼓过像mongodb.redis.cassandra.neo4j等Nosql数据库.其实一直想写博客分享下工作上的零零碎碎 ...