小白一个,总结一下遇到的问题。
一个小demo,它实现的功能是拖拽第1个div当它触碰到第2个div时,第2个div背景色改变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
window.onload = function (){
var oDiv = document.getElementsByTagName("div")[0];
var fix1=document.getElementsByTagName("div")[1];
var fix2=document.getElementsByTagName("div")[2];
console.log(fix1.offsetLeft,fix2.offsetLeft);
drag(oDiv,fix1);
function drag(obj,fix){
obj.onmousedown = function (ev){
if(obj.setCapture){obj.setCapture();}
var ev = window.event || ev;
var left = ev.clientX - obj.offsetLeft;
var top = ev.clientY - obj.offsetTop;
document.onmousemove = function (ev){
var ev = window.event || ev;
//2.限制范围 left
var l = ev.clientX - left;
var t = ev.clientY - top;
if(l < 0){l = 0;}
if(l > document.documentElement.clientWidth-obj.offsetWidth){
l = document.documentElement.clientWidth-obj.offsetWidth;
}
if(t < 0){t = 0;}
if(t > document.documentElement.clientHeight-obj.offsetHeight ){
t = document.documentElement.clientHeight-obj.offsetHeight;
}
obj.style.left = l + "px";
obj.style.top = t + "px";
//3
if(fix1){
var fix_t=fix1.offsetTop;
var fix_l=fix1.offsetLeft;
//console.log(t+obj.offsetHeight,fix_t);
if((t+obj.offsetHeight)>=fix_t){
fix1.style.background="orange"
}
}
}
return false; //ie低版本不支持
}
obj.onmouseup = function (){
document.onmousemove = "";
if(obj.releaseCapture){obj.releaseCapture();}; //在IE上使用全局捕获清除默认行为
}
}
}
</script>
</head>
<body>
<div style="width: 100px;height: 100px;background: red;position: absolute;">1</div>
<div style="width:200px;height:200px;background:#abc;position:absolute;
top:50%;left:50%;transform:translateX(-50%) translateY(-50%) ">2</div>
<div style="width:200px;height:200px;background:#bca;position:absolute;
top:50%;left:50%;margin-top: -100px; opacity:0.5">3</div>
</body>
</html>
在使用transform:translateX(-50%) tanslateY(-50%);
实现第2个div居中时,产生一个bug。即当第1个div边缘碰触到第2个div边缘时,并没有改变背景色。而是继续向下移动第2个div高度的一半(这里正好是100px)时,背景色发生改变。
经过检查
if((t+obj.offsetHeight)>=fix_t){
fix1.style.background="orange"
}
//if()里面的判断是指第1个div的下边缘 触碰或超过 第2个div的上边缘时 背景色改变
这行代码并没有问题。而问题出现在transform:translateX(-50%) tanslateY(-50%);
这上面。
现在在html文档里再添加第3个div,这里不用translateY(-50%),用margin-top:-100px;
<div style="width:200px;height:200px;background:#bca;position:absolute;
top:50%;left:60%;margin-top: -100px; opacity:0.5">2</div>
然后在js代码开始处添加一行console.log(fix1.offsetTop,fix2.offsetTop);
在chrome F12里分别显示 319 219。
从图中看到,第2个div和第3个div是在同一水平线上的。但通过console.log打印出来的值相差了100,正好是第2个div宽度的一半,也就是通过transform:translateY(-50%);往回移动的距离。
再做一个小测试。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height: 100px;width: 100px;background: red"></div>
<p>飞机卡就放大</p>
</body>
</html>
现在显示为最左边的这个效果
现在给div加一个margin-top: 50px;
显示为中间效果。也就是div和p标签都往下移动了50px;现在如果打印一下div的offsetTop会返回一个58。
然后我将 margin-top: 50px;
改成transform: translateY(-50px);
效果显示为最右边的效果。现在只显示一个向下移动50px的div,p标签被div覆盖了。这里打印一下返回一个8。
也就是说div并没有发生移动。。。可明明右边的效果图显示div向下移动了50px。
可以这样理解:在使用transform: translateY(-50px);
后,div虽然产生了位移,但div在原来的位置上还是占位的。这就像给一个元素position:relative;一样,当这个元素被移动时,在原来的位置上该元素仍占位。
所以使用transform: translateY(-50px);
以后虽然div看上去是移动了50px,但实际上div本身并没有移动,只是div的一个“副本”被移动上去了。