使用translate对元素造成类似position:relative的影响

本文介绍了在前端开发中,使用`translate`对元素进行位移时出现的一个bug。当第一个div触碰第二个div边缘时,背景色未立即改变,而是继续移动半个div高度才响应。问题出在`translateY(-50%)`上,它导致元素实际位置并未改变,而是在原位置占用空间,类似于`position:relative`的效果。添加第三个div并对比`margin-top`与`translateY`的不同效果,进一步验证了这一现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小白一个,总结一下遇到的问题。

一个小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的一个“副本”被移动上去了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值