一、实现的效果是在限制范围内拖拽div+吸附+事件捕获。

这里需要理解的是事件捕获,这个事件捕获也是为了兼容div在拖拽过程中,文本不被选中这个问题。

如此良辰美景,拖拽也可以很洒脱哈。先看看图,

二、一步步的实现这个拖拽过程的几个要求

(一)拖拽起来

里面的边框是表示页面哦(我们的屏幕所能看到的东东)。

获取移动距离的思路:

记录鼠标按下和鼠标抬起两次的坐标,然后相减,再加上div跟边缘之间的间距。就得到移动距离。

之前我也在这里困惑了,不明白为什么还要再加上offsetLeft。原因就是clientX获取到的是数值是不加上div跟边缘的距离,不是marin,也不是padding,而是浏览器渲染的问题。

[下面是我自己的理解:

终于明白这个移动距离是如何计算出来的:

将式子化简之后,得到的就是移动后的Div  clientX-移动前clientX,然后再加上offsetLeft,因为这个clientX是没有把边缘计算下去,为了获取准确的数值,要把浏览器默认的边缘计算下去。

如图所以:鼠标移动过的距离就是我用红色画出部分再加上div跟边缘之间的offsetLeft(X轴方向)和offsetTop(Y轴方向)。

如果上面式子不好理解,就把他化简之后来看,就明白了。]

距离获取完成。

现在就可以通过鼠标的三个事件onmousedown、onmousemove、onmouseup来拖拽鼠标。当鼠标移动时,就不断地更改div的left和top属性

oDiv2.style.left = l +'px';
Div2.style.top = t +'px';

最后,当鼠标抬起时,要释放onmousedown和onmousemove事件。

this.onmousedown = null;
this.onmousemove = null;

(二)边缘吸附

边缘吸附的原理so easy。

给一个判断条件,当div运动到距离上下左右边缘的距离小于某一个值时,这时就把left和top的值更改为边缘的值。这样div就贴到边缘上去。

                      var l1= oDiv1.offsetWidth - oDiv2.offsetWidth;        //限制小div在大div中拖拽,计算能拖拽的max距离var t1 = oDiv1.offsetHeight - oDiv2.offsetHeight;if(l > l1-50){l = l1;}if(l < 50){l = 0;}if(t > t1-50){t = t1;}if(t < 50){t = 0;}                    

(三)拖拽过程不被文字选中

div在拖拽过程中,在div中的文本文字总是会被选中,为了解决这个问题,要使用一个叫做事件捕获的知识。

1、先理解一下什么是事件捕获

是跟事件冒泡相反的一种模型。事件捕获的是最后获得事件的是最小的子元素。事件冒泡最后获得事件的是父元素。

之所以在拖拽过程中,div中的文字会被选中就是因为我没有处理好事件冒泡的问题。要解决这个问题,解铃还须系铃人,就把事件冒泡的问题处理好久ok。

         if(oDiv2.setCapture)                             //IE{document.onmousemove = moveFn;document.onmouseup = upFn;oDiv2.setCapture();                          //事件捕获后,所有事件都集中到这个divreturn false;                                //FF、Chrome、IE9}else                                            //FF、chrome{document.onmousemove = moveFn;               //!!!!根源所在,在优化版1中,设置为oDiv2.onmousemove时拖拽一次后无法再拖拽document.onmouseup = upFn;}

记得事件捕获后,当鼠标抬起时,也好释放

oDiv2.releaseCapture();

三、div拖拽的详细代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>限制范围内拖拽</title><style>*{margin: 0;padding: 0;}#div1{width: 500px;height: 500px;background: #CCC;position: relative;}#div2{width: 100px;height: 100px;background: green;position: absolute;left: 0;top: 0;}</style><script>window.onload = function(){var oDiv1 = document.getElementById('div1');var oDiv2 = document.getElementById('div2');        var disX,disY;/*--------------开始拖拽div2-----------------*/oDiv2.onmousedown = function(evt)                    //oDiv2.onmousedown表示按下这个对象,, document.onmouseup整个文档对象(这里把div改成document是防止弄丢div)
        {var oEvent = evt || window.event;                //evt兼容FF/Chrome
disX = oEvent.clientX - oDiv2.offsetLeft;      //-oDiv2.offsetLeft的距离是为了减去div与视口边框的距离
             disY = oEvent.clientY - oDiv2.offsetTop;if(oDiv2.setCapture)                             //IE
            {document.onmousemove = moveFn;document.onmouseup = upFn;oDiv2.setCapture();                          //事件捕获后,所有事件都集中到这个divreturn false;                                   //FF、Chrome、IE9
            }else                                            //FF、chrome
            {document.onmousemove = moveFn;               //!!!!根源所在,在优化版1中,设置为oDiv2.onmousemove时拖拽一次后无法再拖拽
                document.onmouseup = upFn;}function moveFn(evt)                 //把document重新改为div,利用setCapture事件捕获,把事件都集中在一个物体上
            {var oEvent = evt || window.event;var l = oEvent.clientX - disX;            //计算鼠标移过的距离var t = oEvent.clientY - disY;var l1= oDiv1.offsetWidth - oDiv2.offsetWidth;        //限制小div在大div中拖拽,计算能拖拽的max距离var t1 = oDiv1.offsetHeight - oDiv2.offsetHeight;if(l > l1-50){l = l1;}if(l < 50){l = 0;}if(t > t1-50){t = t1;}if(t < 50){t = 0;}oDiv2.style.left = l +'px';oDiv2.style.top = t +'px';}function upFn(){this.onmousedown = null;this.onmousemove = null;if(oDiv2.releaseCapture)                                   //如果事件捕获存在,则释放事件捕获
                {oDiv2.releaseCapture();}}return false;                                              //阻止浏览器默认事件
        };};</script>
</head>
<body>
<div id="div1">使用了事件捕获后,现在拖拽div中的问题可不应该被选中了哦</div>
<div id="div2">helloworld helloworld</div>
</body>
</html>

View Code

[题外话:优化版拖拽再次无法拖拽(已解决:原因是document和oDiv2.onmousemove的问题)]

理解事件捕获。在限制范围内拖拽div+吸附+事件捕获相关推荐

  1. JS中鼠标拖拽div(onmousedown、onmousemove、onmouseup)

    onmousedown:鼠标的按下事件 onmouseove:鼠标的移动事件 onmouseup:鼠标的松开事件 思路: 想实现鼠标拖拽div移动的效果,就得先获取到div,然后给div绑定鼠标按下的 ...

  2. 使用HTML5的Canvas标签实现绘图板内拖拽元素

    第一次在csdn发表文章,纯属试水之作.希望各位多多指教. 直奔主题吧.本人使用了一下HTML5的Canvas标签之后,挺好用的各种画线条,图案等.能实现对Canvas标签内的像素进行随意编辑.加上各 ...

  3. UnityUGUI[Slider]拖拽抬起事件

    因为最近项目需要做个拖拽条,但是跟正常的不太一样 所以需要一个拖拽抬起事件,但是Slider并没给自带的拖拽事件,而且Slider好像重写了EventSystem的IEndDragHandler的方法 ...

  4. JS中鼠标拖拽div(2)(setCapture()方法和releaseCapture()方法)

    接着鼠标拖拽div(1)解决问题,当在拖拽事件所在的页面按下键盘的ctrl+A全选后,再去拖拽div,浏览器会默认去搜索网页中的内容,拖拽功能就会失效,(搜索网页内容是浏览器的默认行为,所以要想不发生 ...

  5. html div 可鼠标滚动,js实现鼠标拖拽div左右滑动

    本文实例为大家分享了js鼠标拖拽div左右滑动的具体代码,供大家参考,具体内容如下 Title body{ position: relative; margin:0; padding:0; width ...

  6. vue 拖拽div 自定义div拖拽

    js 可拖拽div内容框记录 1.css样式 .dragDrop{width:220px;height:88px;line-height:88px;text-align: center;backgro ...

  7. 用鼠标左右拖拽 html,js实现鼠标拖拽div左右滑动

    本文实例为大家分享了js鼠标拖拽div左右滑动的具体代码,供大家参考,具体内容如下 Title body{ position: relative; margin:0; padding:0; width ...

  8. DOM-12 【模拟桌面待讲评】鼠标事件深入、点击与拖拽分离、双击事件

    鼠标事件深入 点击事件 = mousedown + mouseup position: absolute 会将内联元素变为块级(比如a) a标签的协议限定符(伪协议,防止跳转和刷新,让href不生效) ...

  9. 事件 绑定,取消冒泡,拖拽 ,点击,事件委托习题

    事件知识的,冒泡,绑定,委托 <script type="text/javascript">//事件绑定 取消 var div=document.getElements ...

最新文章

  1. 2021年大数据常用语言Scala(十五):基础语法学习 元组  重点掌握
  2. java 程序运行过程 简介
  3. Python语言环境错误:不支持的语言环境设置
  4. Spring的工具类,方便在非spring管理环境中获取bean
  5. 中断方式下进行串口通讯的正确方法
  6. 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)
  7. SSAS系列——【08】多维数据(程序展现Cube)
  8. c语言即时通讯软件源码,即时通讯软件源码-基于c语言即时通讯软件代码实现
  9. (数据库系统概论|王珊)第九章关系查询处理和关系优化-第三节:查询优化之代数优化
  10. python 学习手册重点
  11. 工业相机在全息成像中的应用
  12. EXCEL表格将两列数据进行排列组合
  13. 网络营销成功案例分析篇:NIKE网络营销案例
  14. 手机人像摄影入门简易四步法
  15. matlab图像编码实验,数字图像处理实验和matlab程序代码数字图像处理实验.doc
  16. CnOpenData中国理财产品数据
  17. aptana+php++插件,aptana插件
  18. 常用的八个思维导图工具
  19. 介绍Hosts文件和DNS及DNS的解析过程
  20. TensorFlow学习(11)——卷积神经网络

热门文章

  1. 查车的行驶轨迹_怎么查车辆行驶轨迹?
  2. 使用【Sources】源文件视图和RTL编辑器
  3. 【Indiegogo众筹】$99高性价比RK3399超小型mini主机
  4. Win8/Win8.1常见错误代码的解决方法汇总
  5. eclipse引入svn插件,并将项目同步到svn
  6. Struts2学习第二天——动态方法调用
  7. linux 用户行为审计update1
  8. JBoss Seam 3.0.0.Beta2 发布
  9. python做ui自动化_[python]RobotFramework自定义库实现UI自动化
  10. matlab把cell矩阵转换成能处理的数据