理解事件捕获。在限制范围内拖拽div+吸附+事件捕获
一、实现的效果是在限制范围内拖拽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+吸附+事件捕获的更多相关文章
- JS之scrollTop、offsetHeight和offsetTop等属性用法详解和拖拽div
标题中的几个相关相关属性在网页中有这大量的应用,尤其是在运动框架中,但是由于有些属性相互之间的概念比较混杂或者浏览器兼容性问题,导致掌握起来比较有难度,下面就介绍一下相关属性的用法.先来看一张比较经典 ...
- 简洁的drag效果,自由拖拽div的实现及注意点
偶然间看到了以前做的一个简洁的div拖拽效果,修改了一下加点注释,经测试完美通过firefox/chrome/ie6-11,现拿来分享一下. 先说一下实现原理及要点,最主要的有三步.第一步是mouse ...
- JS拖拽div(移动)
<!doctype html><html><head> <meta charset="utf-8"> <title>JS ...
- 可拖拽div
在开发的时候需要一个可拖拽的prompt弹框.自己写了一个,大概思路为: 1.获取鼠标左键按下移动的起点坐标(x,y). 2.获取div的left和top属性. 3.得到鼠标坐标到左上角的距离(x-t ...
- Javascript 事件对象进阶(二)拖拽的应用 - 登录框的拖拽
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Javascript 事件对象进阶(一)拖拽的原理
拖拽原理 鼠标和Div的相对距离不变 三大事件 把拖拽加到document上 拖拽简单点来说就是不停的更改物体到页面左边&顶部的距离! 那么如何计算出物体到页面左端的距离呢? 当鼠标按下的时候 ...
- jquery监听事件on写法以及简单的拖拽效果
引子——关于jquery的某些写法 我先不对监听事件做解释,我们先来看下jquery的一些写法吧!我们最常用的是jquery的css()方法,相信大家都会用! 假如用css设置一个属性,我们写法如下: ...
- 点滴积累【JS】---JS小功能(onmousedown实现鼠标拖拽div移动)
效果: 思路: 利用onmousedown事件实现拖拽.首先获得鼠标横坐标点和纵坐标点到div的距离,然后当鼠标移动后再用可视区的距离减去横纵坐标与div的距离.然后在判断不让DIV移出可视区,然后再 ...
- 自由拖拽DIV实现
最近在做的项目有个效果是要实现div随意拖拽改变大小,前端框架选择的是vue.js,UI用的是element,拖拽效果可以很简单的实现,但是在拖拽过程中发现会对其他元素实现全选效果,因此最后选择使用元 ...
随机推荐
- KeepAlive详解
KeepAlive既熟悉又陌生,踩过坑的同学都知道痛.一线运维工程师踩坑之后对于KeepAlive的总结,你不应该错过! 最近工作中遇到一个问题,想把它记录下来,场景是这样的: 从上图可以看出,用户通 ...
- 在ADS上由于volatile惹得祸
C语言关键字volatile是一个危险的东东,笔者再用ADS做S3C2440定时器中断实验就因为这个关键字出了错.出现错误情况的准确描述是:定义一个变量时没有用volatile关键字,而且紧接着whi ...
- Spring和Hibernate相遇
Spring是一个很贪婪的家伙,看到他的长长的jar包列表就知道了,其实对于hibernate的所有配置都是可以放在Spring中来进行得,但是我还是坚持各自分明,Spring只是负责自动探测声明类( ...
- Python的数字类型及其技巧
Python中的数字类型 int float fractions.Fraction decimal.Decimal 数字的舍与入 int(f):舍去小数部分,只保留整数部分,所以int(-3.8)的结 ...
- 意犹未尽而来的第一篇Android 逆向
游戏:咕噜王国大冒险 平台:android 目标: 1. 去除乱七八糟提示(本篇目标) 2. 去除google弹窗 3. 破解“all stages” 破文开始: 1. 使用APKIDE反编译:搜索字 ...
- python之--输入输出
python之输出 用print加上字符串,就可以向屏幕上输出指定的文字.用代码实现如下: >>> print "i love baby!" i love bab ...
- bzoj 3527: [Zjoi2014]力 快速傅里叶变换
题意: 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. fft的那一堆东西还是背不到啊...这次写虽说完全自己写的,但是还是在参见了以前fft程序的情况下调了很久,主要在如下几点 ...
- xHtml+css学习笔记
第一节 xHTML规范 *文档方面 -必须定义文档类型(DTD)和名字控件 *标签方面 -所有标签均要小写.关闭.合理嵌套.ID不能重复 -标签属性药有值,属性值要加印号且不能为空 -图片一定要加上a ...
- 【 CodeForces - 392C】 Yet Another Number Sequence (二项式展开+矩阵加速)
Yet Another Number Sequence Description Everyone knows what the Fibonacci sequence is. This sequence ...
- 【BZOJ 2820】 YY的GCD (莫比乌斯+分块)
YY的GCD Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少 ...