使用JS制作一个鼠标可拖的DIV(二)——限制区域移动
这次是要对上一篇的内容进行扩展。
由于需要对可拖动的 DIV 进行一个区域范围的限制,所以要给于一个容器,让可拖动的 DIV 元素不能逃出该容器的大小范围。
一、思路
1.在外层增加一个 DIV 容器,并设置好容器的大小。(即:宽和高)
当容器存在边框的时候,由于这里还没找到获取的方法,所以,在容器边框大于 0 的时候,获得的容器的限制区域的坐标会有误差。
为了避免这情况,可以在多加一次容器,有边框样式的在外层,无边框样子的在内层。
例:
<style>
#mainContainer {
border: 10px solid #990000;
width: 600px;
height: 300px;
} #innerContainer {
width: 100%;
height: 100%;
} #Drag {
/*border: 5px solid #C4E3FD;*/
background: #C4E3FD;
width: 50px;
height: 50px;
top: 50px;
left: 50px;
z-index: 2;
} #Drag2 {
/*border: 5px solid #C4E3FD;*/
background: #ff0000;
width: 50px;
height: 50px;
top: 50px;
left: 50px;
z-index: 3;
}
</style> <div id="mainContainer">
<div id="innerContainer">
<div id="Drag" onmousedown="moveBind(this, event)">1</div>
<div id="Drag2" onmousedown="moveBind(this, event)">2</div>
</div>
</div>
<br />拖放状态:<span id="idShow">未开始</span>
2.为了方便获得元素的位置和大小,先写一个方法来辅助(谷歌不能用了可恶orz,只能百度出这个方法并稍微做点修改)。
//获得元素的坐标与大小。
function findPosition(oElement) {
var x2 = 0;
var y2 = 0;
var width = oElement.clientWidth;
var height = oElement.clientHeight;
//alert(width + "=" + height);
if (typeof (oElement.offsetParent) != 'undefined') {
for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
posX += oElement.offsetLeft;
posY += oElement.offsetTop;
}
x2 = posX + width;
y2 = posY + height;
return [posX, posY, x2, y2, width, height]; } else {
x2 = oElement.x + width;
y2 = oElement.y + height;
return [oElement.x, oElement.y, x2, y2, width, height];
}
}
这里以数组的形式返回元素的 X 开始坐标和 Y 开始坐标,X 结束坐标和 Y 结束坐标,元素真实的宽与高(不算边框)
3.在鼠标按下事件里,先获得容器的位置数据:
//获得容器坐标。
var container = findPosition(document.getElementById("innerContainer"));
var containerLeft = container[0];
var containerTop = container[1];
var containerWidth = container[4];
var containerHeight = container[5];
4.计算拖动 DIV 元素可移动的区域坐标:
/*计算出容器的范围坐标。*/ //开始 X 坐标。
var startX = containerLeft;
//开始 Y 坐标。
var startY = containerTop;
//结束 X 坐标。
var maxX = startX + containerWidth - width;
//结束 Y 坐标。
var maxY = startY + containerHeight - height;
开始 X 坐标 = 容器的左上角 X 坐标。
开始 Y 坐标 = 容器的左上角 Y 坐标。
结束 X 坐标 = 开始 X 坐标 + 容器的宽度 - 拖动 DIV 元素的宽度
结束 Y 坐标 = 开始 Y 坐标 + 容器的高度 - 拖动 DIV 元素的高度
5.当区域内存在多个可拖动的 DIV 元素时,要把当前鼠标点击的那个 DIV 设置成置顶显示。
//获得最大 Z 坐标。
function getMaxIndex() {
var index = 0;
var ds = document.getElementById('innerContainer').getElementsByTagName('div');
var length = document.getElementById('innerContainer').getElementsByTagName('div').length; for (var loop = 0; loop < length; loop++) {
if (ds[loop].style.zIndex > index) index = ds[loop].style.zIndex;
} return parseInt(index);
}
该方法遍历容器内的所有 DIV 元素(即:可拖动元素),取得它们当中z-Index最大的值。
然后,设置点击元素的 z-Index 值:
//鼠标选中的元素设置成顶层。
obj.style.zIndex = getMaxIndex() + 1;
/*******************以上方法是在鼠标按下事件里 onmousedown ******************/
/*******************以下方法是在鼠标按下事件里 onmousemove ******************/
6.在移动事件里,修改元素位置的外层加上如下这条件。
//不可以超出指定的范围。
if (moveLeft >= startX && moveTop >= startY && moveLeft <= maxX && moveTop <= maxY) {
//当移动位置在范围内时,元素跟随鼠标移动。
obj.style.left = moveLeft + "px";
obj.style.top = moveTop + "px";
}
这条件表示:移动的位置在容器范围内时,元素才可以跟随鼠标移动。
但是,现在这样的做法,当鼠标快速拖出容器区域时,元素就会停止不动,但并没有移动到最边界,同时,鼠标在区域外并没有放开按键,移动鼠标时元素并不会跟着移动。
解决的思路是:
(1)当元素水平(X坐标)移动的位置没有达到或超出容器限制区域的 X 坐标区域时。
继续修改拖动元素的 X 坐标位置。
(2)当元素水平(X坐标)移动的位置超出容器限制区域的最大 X 坐标(即:容器右下角的 X 坐标)区域时(即:限制区域的右边),将元素的 X 坐标设置成最大 X 坐标值。
if (moveLeft >= startX && moveLeft <= maxX) {
obj.style.left = moveLeft + "px";
} else if (moveLeft > maxX) {
obj.style.left = maxX + "px";
}
(3)当元素水平(X坐标)移动的位置小于容器限制区域的开始 X 坐标(即:容器左上角的 X 坐标)区域时(即:限制区域的左边),将元素的 X 坐标设置成最小 X 坐标值。
if (moveLeft >= startX && moveLeft <= maxX) {
obj.style.left = moveLeft + "px";
} else if (moveLeft > maxX) {
obj.style.left = maxX + "px";
} else if (moveLeft < startX) {
obj.style.left = startX + "px";
}
(4)Y 坐标同以上(1)(2)(3):
if (moveTop >= startY && moveTop <= maxY) {
obj.style.top = moveTop + "px";
} else if (moveTop > maxY) {
obj.style.top = maxY + "px";
} else if (moveTop < startY) {
obj.style.top = startY + "px";
}
完成了!这时,鼠标拖动到区域外面时,元素同样会跟随鼠标的位置在容器内移动。
二、以下是完整源码:
JS部分:
//获得元素的坐标与大小。
function findPosition(oElement) {
var x2 = 0;
var y2 = 0;
var width = oElement.clientWidth;
var height = oElement.clientHeight;
//alert(width + "=" + height);
if (typeof (oElement.offsetParent) != 'undefined') {
for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
posX += oElement.offsetLeft;
posY += oElement.offsetTop;
}
x2 = posX + width;
y2 = posY + height;
return [posX, posY, x2, y2, width, height]; } else {
x2 = oElement.x + width;
y2 = oElement.y + height;
return [oElement.x, oElement.y, x2, y2, width, height];
}
} function moveBind(obj, evnt) {
//获得元素坐标。
var left = obj.offsetLeft;
var top = obj.offsetTop;
var width = obj.offsetWidth;
var height = obj.offsetHeight; //计算出鼠标的位置与元素位置的差值。
var cleft = evnt.clientX - left;
var ctop = evnt.clientY - top; //获得容器坐标。
var container = findPosition(document.getElementById("innerContainer"));
var containerLeft = container[0];
var containerTop = container[1];
var containerWidth = container[4];
var containerHeight = container[5]; /*计算出容器的范围坐标。*/ //开始 X 坐标。
var startX = containerLeft;
//开始 Y 坐标。
var startY = containerTop;
//结束 X 坐标。
var maxX = startX + containerWidth - width;
//结束 Y 坐标。
var maxY = startY + containerHeight - height; //鼠标选中的元素设置成顶层。
obj.style.zIndex = getMaxIndex() + 1; //输出显示。
//show("idShow", startX, startY); document.onmousemove = function (doc) {
//计算出移动后的坐标。
var moveLeft = doc.clientX - cleft;
var moveTop = doc.clientY - ctop; //设置成绝对定位,让元素可以移动。
obj.style.position = "absolute"; //不可以超出指定的范围。
if (moveLeft >= startX && moveTop >= startY && moveLeft <= maxX && moveTop <= maxY) {
//当移动位置在范围内时,元素跟随鼠标移动。
obj.style.left = moveLeft + "px";
obj.style.top = moveTop + "px";
} else {
/****************以下为处理当鼠标的位置不在范围内里,鼠标的移动,里面的元素也要跟着移动*****************/
//向右移动时,如果移动坐标没有大于最大 X 坐标,则移动,否则设置成最大 X 坐标的值。
if (moveLeft >= startX && moveLeft <= maxX) {
obj.style.left = moveLeft + "px";
} else if (moveLeft > maxX) {
obj.style.left = maxX + "px";
} else if (moveLeft < startX) {
obj.style.left = startX + "px";
} //向下移动时,如果移动坐标没有大于最大 Y 坐标,则移动,否则设置成最大 Y 坐标的值。
if (moveTop >= startY && moveTop <= maxY) {
obj.style.top = moveTop + "px";
} else if (moveTop > maxY) {
obj.style.top = maxY + "px";
} else if (moveTop < startY) {
obj.style.top = startY + "px";
}
} show("idShow", moveLeft, moveTop);
} document.onmouseup = function () {
document.onmousemove = function () { }
};
} //获得最大 Z 坐标。
function getMaxIndex() {
var index = 0;
var ds = document.getElementById('innerContainer').getElementsByTagName('div');
var length = document.getElementById('innerContainer').getElementsByTagName('div').length; for (var loop = 0; loop < length; loop++) {
if (ds[loop].style.zIndex > index) index = ds[loop].style.zIndex;
} return parseInt(index);
} //显示坐标信息。
function show(id, x, y) {
document.getElementById(id).innerHTML = "left:" + x + ";top:" + y;
}
HTML部分:
<style>
#mainContainer {
border: 10px solid #990000;
width: 600px;
height: 300px;
} #innerContainer {
width: 100%;
height: 100%;
} #Drag {
/*border: 5px solid #C4E3FD;*/
background: #C4E3FD;
width: 50px;
height: 50px;
top: 50px;
left: 50px;
z-index: 2;
} #Drag2 {
/*border: 5px solid #C4E3FD;*/
background: #ff0000;
width: 50px;
height: 50px;
top: 50px;
left: 50px;
z-index: 3;
}
</style> <div id="mainContainer">
<div id="innerContainer">
<div id="Drag" onmousedown="moveBind(this, event)">1</div>
<div id="Drag2" onmousedown="moveBind(this, event)">2</div>
</div>
</div>
<br />拖放状态:<span id="idShow">未开始</span>
使用JS制作一个鼠标可拖的DIV(二)——限制区域移动的更多相关文章
- 使用JS制作一个鼠标可拖的DIV(一)——鼠标拖动
使用 JS 来实现一个可拖动的DIV,主要是使用到以下几个事件: 1.鼠标按下:DIV元素的onmousedown. 2.鼠标按住拖动:document 的 onmousemove 元素. 3.鼠标放 ...
- 使用JS制作一个鼠标可拖的DIV(四)——缩放
原理与鼠标拖动 DIV 相同. 下面就先实现一个在DIV的右上角显示一个小正方形(类似). 当鼠标按下并拖动时,DIV会以要拖动的元素的左下角的坐标点定位,根据鼠标的拖动,按比例的扩大或缩小. 一.思 ...
- 使用JS制作一个鼠标可拖的DIV(三)——移动带图片DIV
当DIV元素里,存在图片元素的时候,会使拖动出现异常. 因为图片元素本身就支持拖动,所以,只要在图片标签加入:draggable='false'. 如下: <div onmousedown=&q ...
- 用JS制作一个信息管理平台完整版
前 言 JRedu 在之前的文章中,介绍了如何用JS制作一个实用的信息管理平台. 但是那样的平台功能过于简陋了,我们今天来继续完善一下. 首先我们回顾一下之前的内容. 1.JSON的基础知识 ...
- three.js 制作一个三维的推箱子游戏
今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...
- JS制作一个创意数字时钟
通过js代码制作一个创意数字时钟 通过JS代码实现创意数字时钟效果如下:由数字化的卡通形象图片取代常规的数字显示当前实时北京时间.具体效果示例: 核心重点: (1)Date方法的初步了解 (2)构建模 ...
- 用js制作一个计算器
使用js制作计算器 <!doctype html> <html lang="en"> <head> <meta charset=" ...
- 用js写一个鼠标坐标实例
HTML代码 写一个div来作为鼠标区域 div中写一个span显示坐标信息 <body> <div id=""> <span></spa ...
- 用Phaser来制作一个html5游戏——flappy bird (二)
在上一篇教程中我们完成了boot.preload.menu这三个state的制作,下面我们就要进入本游戏最核心的一个state的制作了.play这个state的代码比较多,我不会一一进行说明,只会把一 ...
随机推荐
- Spring Data Solr教程(翻译)
大多数应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗并且它们由于沉重的数据库加载而拖垮你的应用的性能 这就是为什么转移负载到一个外部的搜索服务器是一个不错的主意,Apache Solr ...
- freemaker自定义分页控件实现
<link href="${res}/css/pages-jhdb.css" rel="stylesheet" type="text/css&q ...
- Spring中注解事务方面的问题
我们可以在spring的配置文件beans.xml中对事务进行注解配置,这样在相应的类中就不用对事务进行管事,对于某个类,想单独交给spring来管理,那么就在相应的类上加入@Transactiona ...
- window.parent != window 解决界面嵌套问题
页面在被嵌套的时,效果:,,如果用户点击“刷新”,该问题即可解决. 如果想通过代码解决的话,这个问题属于客户端的问题,不是服务器端的问题. 如果直接写:window.location.href = “ ...
- 小学生玩ACM----广搜
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- Converting a .jks Key Store to a .pem Key Store
In order to convert a Java key store into a Privacy Enhanced Mail Certificate, you will need to use ...
- too many automatic redirections were attempted
用HttpClient时发现一下页面跳转现象. 页面A要求授权自动跳转到页面B, 页面B进行了授权,在HTTP Header里要求SetCookie并跳转到页面A. 再次请求页面A的时候没有带上此Co ...
- 寻ta分析与站点内容
从 寻ta 突然来的訪问量就開始在想.站点内容是否才是真正须要的东西. 寻ta分析 作为一篇文章带来的影响,我们能够看看訪问会话. 日期 訪问量 5.5 9 5.6 4618 5.7 1216 5.8 ...
- CUDA从入门到精通
http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...
- 权限执行[Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?
每日一贴,今天的内容关键字为权限执行 RunTime.exec()这个接口可以说是给我们开发者供给了一个很好的直观操纵底层操纵系统的机遇,但是这个接口的使用还有很多需要注意的问题.由于要完全的分析这个 ...