大致思路:
鼠标按下并且移动的时候,使得鼠标点击的div跟随鼠标移动,松开按键或者鼠标移开div时,div不跟随移动。而图层跟随鼠标移动只需要计算出鼠标的移动位置相对于鼠标按下时的原位置,就可以得到偏移量,再用图层的原位置减去偏移量,就是图层的移动后位置。所以大致分为三个步骤。
首先,鼠标的按下事件
let flag = 0; //确定该图层是否鼠标处于按下状态
let oldMX = 0 //鼠标的原X位置
let oldMY = 0 //鼠标的原Y位置
let oldDX = 0 //图层的原X位置
let oldDY = 0 //图层的原Y位置
/*下面两个函数是为了获取图层位置,原文https://www.jb51.net/article/24348.htm*/
function getTop(e){
var offset=e.offsetTop;
if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
return offset;
}
function getLeft(e){
var offset=e.offsetLeft;
if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
return offset;
}
function getE(obj) { //鼠标按下事件
let e = event || window.event; //获取鼠标对象
flag = 1 //让flag = 1表示该图层可以移动
/*这里是获取图层的原位置,如果一开始没有设置css样式的left和top的话,
需要用到之前我们自定义的获取left和top函数*/
if( obj.style.left == ''|| obj.style.top == '') {
oldDX = getLeft(obj)
oldDY = getTop(obj)
}
else{
oldDX = obj.style.left
oldDY = obj.style.top
}
/*将获取的图层位置存起来*/
oldDX = parseInt(oldDX)
oldDY = parseInt(oldDY)
/*同样是为了防止没有定义letf和top时,鼠标点击后div回到左上角的情况*/
obj.style.left = oldDX + 'px'
obj.style.top = oldDY + 'px'
/*因为用相对位置自动排版的时候,不能改变div的位置,所以要改变为绝对位置*/
obj.style.position = "absolute"
oldMX = e.clientX //获取鼠标的x和y并存起来
oldMY = e.clientY
}
接下来就是鼠标移动事件
function move(obj) {
let e = event || window.event;
if(flag == 1) //要确定鼠标已经按下,才会改变图层位置
{
/*用div原位置减去鼠标的偏移量,就是图层的现位置*/
obj.style.left = oldDX - (oldMX - e.clientX)+"px"
obj.style.top = oldDY - (oldMY - e.clientY)+"px"
}
}
最后是鼠标松开或者移出div事件
function Cancel(obj) {
if(flag == 1) //同样是确定鼠标已经按下
{
flag = 0 //禁止使用鼠标移动改变div位置
}
}
那么核心代码已经写好了,现在写div
<div id="main" name="init" style="width: 600px;height:400px;float:left;background-color: rgba(245,245,228,0.5) ;z-Index: 120; " onmousedown="getE(this)" onmousemove="move(this)" onmouseup="Cancel(this)" onmouseout="Cancel(this)"></div>
我们可以看到,div一开始并没有设置left和top,也没有设置成绝对位置,所有在页面加载的时候,浏览器会对div自动排版,不会显得很乱。
但是这里我发现又出现一种问题。当有多个div的时候,如果鼠标点击中间的某个div,那么该div会设置成绝对位置,其他相对位置的div就会补上空缺,我们的点击后的div就没有地方放置了。为了避免这种情况·,我们又必须让所有的div都是绝对位置。所以我的思路是一开始的div为相对位置,自动排版。当div全部加载后,再让div从最后一个元素到第一个元素全部设置成绝对位置。
function init() {
let objs = document.getElementsByName("init") //获取所有name是init的对象
for(let i = objs.length-1 ; i >= 0 ; i--) { //从最后到第一个元素遍历
/*先获取定义letf和top,否则换成绝对位置没有left和top时div会移动到左上角*/
let obj = objs[i]
oldDX = getLeft(obj)
oldDY = getTop(obj)
oldDX = parseInt(oldDX)
oldDY = parseInt(oldDY)
obj.style.left = oldDX + 'px'
obj.style.top = oldDY + 'px'
obj.style.position = "absolute"
}
}
那么现在所有代码全部搞定
html部分:
<div id="main1" name="init" style="width: 600px;height:400px;float:left;background-color: rgba(245,245,228,0.5) ;z-Index: 120; " onmousedown="getE(this)" onmousemove="move(this)" onmouseup="Cancel(this)" onmouseout="Cancel(this)"></div>
<div id="main2" name="init" style="width: 600px;height:400px;float:left;background-color: rgba(245,245,228,0.5) ;z-Index: 120; " onmousedown="getE(this)" onmousemove="move(this)" onmouseup="Cancel(this)" onmouseout="Cancel(this)"></div>
<div id="main3" name="init" style="width: 600px;height:400px;float:left;background-color: rgba(245,245,228,0.5) ;z-Index: 120; " onmousedown="getE(this)" onmousemove="move(this)" onmouseup="Cancel(this)" onmouseout="Cancel(this)"></div>
js代码:
<script>
let flag = 0;
let oldMX = 0
let oldMY = 0
let oldDX = 0
let oldDY = 0
function init() {
let objs = document.getElementsByName("init")
for(let i = objs.length-1 ; i >= 0 ; i--) {
let obj = objs[i]
oldDX = getLeft(obj)
oldDY = getTop(obj)
oldDX = parseInt(oldDX)
oldDY = parseInt(oldDY)
obj.style.left = oldDX + 'px'
obj.style.top = oldDY + 'px'
obj.style.position = "absolute"
}
}
//设置移动过的图层在最上方
function ZIndex() {
let objs = document.getElementsByName("init")
for(let i = objs.length-1 ; i >= 0 ; i--) {
let obj = objs[i]
obj.style.zIndex = '120'
}
}
function getTop(e){
var offset=e.offsetTop;
if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
return offset;
}
function getLeft(e){
var offset=e.offsetLeft;
if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
return offset;
}
function getE(obj) {
obj.style.boxShadow = "0 0 10px #dce861" //加了一个选中样式
let e = event || window.event;
flag = 1
if( obj.style.left == ''|| obj.style.top == '') {
oldDX = getLeft(obj)
oldDY = getTop(obj)
}
else{
oldDX = obj.style.left
oldDY = obj.style.top
}
oldDX = parseInt(oldDX)
oldDY = parseInt(oldDY)
obj.style.left = oldDX + 'px'
obj.style.top = oldDY + 'px'
obj.style.position = "absolute"
oldMX = e.clientX
oldMY = e.clientY
ZIndex() //所有的div都是120,让选中的div设置成130,那该div就在最上方
obj.style.zIndex = "130"
}
function move(obj) {
let e = event || window.event;
if(flag == 1)
{
obj.style.left = oldDX - (oldMX - e.clientX)+"px"
obj.style.top = oldDY - (oldMY - e.clientY)+"px"
}
}
function Cancel(obj) {
if(flag == 1)
{
obj.style.boxShadow = 'none' //取消选定
flag = 0
}
}
init(); //执行初始化
</script>
效果图:(因为最开始设置的背景看不清,所有我改了背景颜色)
刚加载网页:
移动图层:
最后移动黄色图层