关于javascript:marginleft导致CSS中styleleft与offsetLeft取值数值上不等的情况

style.left & offsetLeft

<font size=”5px”>left</font> 是css款式中的一个属性,left 属性规定元素的左边缘。该属性定义了定位元素<font color=red>左外边距边界</font>与<font color=red>其蕴含块左边界</font>之间的偏移。(如果 “position” 属性的值为 “static”,那么设置 “left” 属性不会产生任何成果。)具体可参阅W3C school

<font size=”5px”>offsetLeft</font> 是HTML DOM Element对象的一个属性,offsetLeft属性返回<font color=red>以后元素左上角</font>绝对于<font color=red>HTMLElement.offsetParent节点的左边界</font>偏移的像素值。具体可参阅MDN.

当然,style.left返回的是带有”px”的 可读写字符串类型,offsetLeft返回的是只读的数字型,本文中的比拟均是取style.left中的数字值。

代码示例

HTML代码:

    <body>
    ![](images2/pikachu2.jpg)
    <button>btn</button>
    </body>

CSS代码:

    <style>
        * {
            padding: 0;
            margin: 0;
        }

        img {
            position: relative;
            margin-left: 300px;
        }
    </style>

JS代码:

<script>
    function Animate(el, targetP) {
        let currentP = el.offsetLeft  //获取元素的以后地位
        let step = targetP > currentP ? 10 : -10  //每次挪动10px
        let animateTimer = setInterval(() => {
            currentP = el.offsetLeft  //从新获取元素的以后地位
            el.style.left = currentP + step + "px"
            //当指标地位和以后地位的间隔差的绝对值小于要挪动步数的绝对值时,间接挪动到指标地位并革除定时器
            if (Math.abs(targetP - currentP) < Math.abs(step)) {
                el.style.left = targetP + "px"
                clearInterval(animateTimer)
            }
        }, 15)
    }

    let image = document.querySelector("img")
    let btn = document.querySelector("button")
    btn.addEventListener("click", () => {
        Animate(image, 200)
    })

</script>

Animate(el, targetP)作用是将对应DOM元素程度挪动到指定地位。

Animate(image, 200)的目标是将图片程度挪动到200px的地位(因为咱们在图片上设了300px的margin-left值,所以预期的成果应该是图片左移300-200=100px的间隔),但实际上下面代码的运行后果是图片始终右移且永不进行。

从图片里咱们能够看到,当程序运行到27行断点处时,图片对象的style.left数值上是0,其offsetLeft值是300;在程序运行到30行断点处时,图片对象的style.left数值上是290,其offsetLeft值是590。持续执行程序咱们会发现,offsetLeft值始终比style.left大300。

这就是因为图片元素有300px的margin-left值,所以元素自身左上角的在间隔浏览器300px的绿色垂直线上,而元素自身的左外边距边界在浏览器左边缘的蓝色垂直线(画的很粗是为了突显那条线)上,从HTML中能够看到,图像元素的父级就是body,所以它的父亲节点/蕴含图像的盒子就是body自身,body的左边界在蓝色垂直线上,所以style.left=0,而offsetLeft即margin-left的值300;而在第二张图的30行断点处,通过28行后图像曾经程度挪动到left=290px即间隔第一张图片的绿色垂直线290px的地位,此时图片左上角间隔body的左边缘间隔(offsetLeft)为300+290=590,所以两者值始终不相等。

代码示例批改后

那要怎么保障两者值相等呢?天然是要保障第一张图的蓝色和绿色在同一垂直线上,即图片的左外边距边界和图片的左上角位于同一垂直线上,也即去掉margin-left的值,如果切实想要margin-left,也能够在图片的外层套一个绝对定位(position默认值是static,会导致style.left属性有效)的div,把margin-left属性设置在该div上,这样一来图片左外边距边界、图片元素左边界、图片元素父元素左边界均在div的左边界上,就达到了咱们要的成果。

<head>
    <meta charset="UTF-8">
    <title>测试</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        div {
            position: relative;
            margin-left: 300px;
            left: 50px;
        }
        img {
            position: relative;
        }
    </style>
</head>
<body>
<div>![](images2/pikachu2.jpg)</div>
</body>

js局部代码不变。

论断

本文所探讨的状况下,以后元素的<font color=red>margin-left</font>属性若已设值,则style.left与offsetLeft在数值上不等,否则是相等的。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理