前言

关于讲解 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 实现简单的拖拽功能并且可以在特定元素上禁止拖拽的更多相关文章

  1. 非node环境下的vue.js 实现简单的购物车计算功能 样式请无视

    都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用.自己的实现如下: <!DOCTYPE html> <html lang="en"> &l ...

  2. (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能

    利用JavaScript(JS)实现一个九宫格拖拽功能   Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...

  3. JQuery UI的拖拽功能

    JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...

  4. JQuery UI的拖拽功能实现方法小结

    JQuery UI提供的API极大简化了拖拽功能的开发.只需要分别在拖拽源(source)和目标(target)上调用draggable和droppable两个函数即可. 拖拽原理 首先要明确几个概念 ...

  5. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  6. Atitit。D&D drag&drop拖拽功能c#.net java swing的对比与实现总结

    Atitit.D&D drag&drop拖拽功能c#.net java swing的对比与实现总结 1. 实现一个D&D操作一般包括三个步骤: 1 2. .net黑头的拖曳机制 ...

  7. JS实现简单的运行代码 & 侧边广告

    /* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...

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

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

  9. js进阶 12-17 jquery实现鼠标左键按下拖拽功能

    js进阶 12-17 jquery实现鼠标左键按下拖拽功能 一.总结 一句话总结:监听的对象必须是文档,鼠标按下运行mousemove事件,鼠标松开取消mousemove事件的绑定,div的偏移的话是 ...

随机推荐

  1. OPENCV3——从入门到出门

    跑第一个程序的时候经过坑爹的各种设置终于能用了. 如果遇到问题就谷歌或者百度,大牛的博客会给出解决方案的. vs2010+opencv3 目标:把书上的程序挨个敲一遍跑一遍. 现在已经跑了七章了,还有 ...

  2. .net 分布式的未来:微服务

    一.背景&问题 之前框架是一个基于SOA思想设计的分布式框架.各应用通过服务方式提供使用,服务之间通信是RPC方式调用,具体实现基于.NET的WCF通信平台.框架存在如下2个问题: 1.高并发 ...

  3. 总结HTML5的学习方法大汇总

    html5学习方法之技能清单: 必须掌握基本的Web前端开收技术,其中包括:CSS.HTML.DOM.java.Ajax,jquery,Vue,jquery- mobile,zepto等,在掌握这些技 ...

  4. Less的Mixin

    什么是Mixin Less中,允许你将一个类嵌入到另一个类中,被嵌入的类也可以看作变量.换句话说,你可以用一个类定义样式,然后把它当作变量,在另一个类中,只要引用变量的名字,就能使用它的所有属性, L ...

  5. 集合、增强for、泛型

    Collection集合:Collection是层次结构中的根接口,存储的元素为对象,(也就是说只能存储引用数据类型,不能存储基础数据类型),具体可查询API.集合与数组的区别:1.集合只能存放引用数 ...

  6. Spring Cloud 之 Ribbon

    新建Spring Boot工程,命名为ribbon 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"? ...

  7. ACM HDU 1081 To The Max

     To The Max Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. 算法训练 K好数

      算法训练 K好数   时间限制:1.0s   内存限制:256.0MB 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数 ...

  9. 倒水问题 (FillUVa 10603) 隐式图

    题意:本题的题意是给你三个杯子,第一二个杯子是空的,第三个杯子装满水,要求是量出一定容量d升的水.若是得不到d升的水,那就让某一个杯子里面的水达到d',使得d'尽量接近d升. 解题思路:本题是给出初始 ...

  10. git实用攻略(二)

    最近团队的版本控制从svn切换到了git,虽说已经使用git有2年多了,也写了一个实用攻略,但是github上的项目使用经验和公司内部团队协作的使用经验还有很多不同.补充下新的使用体会. 首先还是看一 ...