一、实现的效果是在限制范围内拖拽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 <)
{
l = 0;
}
if(t > t1-50)
{
t = t1;
}
if(t <)
{
t = 0;
}

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

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

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

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

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

         if(oDiv2.setCapture)                             //IE
{
document.onmousemove = moveFn;
document.onmouseup = upFn; oDiv2.setCapture(); //事件捕获后,所有事件都集中到这个div return 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(); //事件捕获后,所有事件都集中到这个div return 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>

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

理解事件捕获。在限制范围内拖拽div+吸附+事件捕获的更多相关文章

  1. JS之scrollTop、offsetHeight和offsetTop等属性用法详解和拖拽div

    标题中的几个相关相关属性在网页中有这大量的应用,尤其是在运动框架中,但是由于有些属性相互之间的概念比较混杂或者浏览器兼容性问题,导致掌握起来比较有难度,下面就介绍一下相关属性的用法.先来看一张比较经典 ...

  2. 简洁的drag效果,自由拖拽div的实现及注意点

    偶然间看到了以前做的一个简洁的div拖拽效果,修改了一下加点注释,经测试完美通过firefox/chrome/ie6-11,现拿来分享一下. 先说一下实现原理及要点,最主要的有三步.第一步是mouse ...

  3. JS拖拽div(移动)

    <!doctype html><html><head> <meta charset="utf-8"> <title>JS ...

  4. 可拖拽div

    在开发的时候需要一个可拖拽的prompt弹框.自己写了一个,大概思路为: 1.获取鼠标左键按下移动的起点坐标(x,y). 2.获取div的left和top属性. 3.得到鼠标坐标到左上角的距离(x-t ...

  5. Javascript 事件对象进阶(二)拖拽的应用 - 登录框的拖拽

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  6. Javascript 事件对象进阶(一)拖拽的原理

    拖拽原理 鼠标和Div的相对距离不变 三大事件 把拖拽加到document上 拖拽简单点来说就是不停的更改物体到页面左边&顶部的距离! 那么如何计算出物体到页面左端的距离呢? 当鼠标按下的时候 ...

  7. jquery监听事件on写法以及简单的拖拽效果

    引子——关于jquery的某些写法 我先不对监听事件做解释,我们先来看下jquery的一些写法吧!我们最常用的是jquery的css()方法,相信大家都会用! 假如用css设置一个属性,我们写法如下: ...

  8. 点滴积累【JS】---JS小功能(onmousedown实现鼠标拖拽div移动)

    效果: 思路: 利用onmousedown事件实现拖拽.首先获得鼠标横坐标点和纵坐标点到div的距离,然后当鼠标移动后再用可视区的距离减去横纵坐标与div的距离.然后在判断不让DIV移出可视区,然后再 ...

  9. 自由拖拽DIV实现

    最近在做的项目有个效果是要实现div随意拖拽改变大小,前端框架选择的是vue.js,UI用的是element,拖拽效果可以很简单的实现,但是在拖拽过程中发现会对其他元素实现全选效果,因此最后选择使用元 ...

随机推荐

  1. Keil的c语言编译器

    我曾经通过查看反汇编代码对KEILC编译器进行了测试,大概有这么一下内容,也得出一些结论. (1)全局变量:如果程序中定义了全局变量,而且初始值不是0.此时,在程序调到main()函数执行前,除了要进 ...

  2. Ionic简介和环境安装

    什么是Ionic Ionic是一个用来开发混合手机应用的,开源的,免费的代码库.可以优化html.css和js的性能,构建高效的应用程序,而且还可以用于构建Sass和AngularJS的优化.ioni ...

  3. lua之mysql编程

    环境搭建 #mysql 安装 sudo apt-get install mysql-server mysql-client # lua mysql 开发驱动安装 sudo apt-get instal ...

  4. ORACLE 定时任务JOB

    http://www.cnblogs.com/xclw/archive/2009/12/04/1616945.html

  5. python类的继承

    继承一个类 如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承: class Person(object): def __init__(self ...

  6. C#中值参数的使用实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 函数的参 ...

  7. The Promise of Deep Learning

    The Promise of Deep Learning By Yoshua Bengio Humans have long dreamed of creating machines that thi ...

  8. 关于MATLAB中的tic toc的问题

    关于MATLAB中的tic toc的问题 其一) MATLAB实际单位时间计时函数的具体应用,在编写程序时,经常需要获知代码的执行实际时间,这就需要在程序中用到计时函数,matlab中提供了以下三种方 ...

  9. JAVA实现前几秒几分钟几天前几年源码

    package com.date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...

  10. 【HDU 1828】 Picture (矩阵周长并,线段树,扫描法)

    [题目] Picture Problem Description A number of rectangular posters, photographs and other pictures of ...