style.left & offsetLeft
left 是css样式中的一个属性,left 属性规定元素的左边缘。该属性定义了定位元素左外边距边界与其包含块左边界之间的偏移。(如果 "position" 属性的值为 "static",那么设置 "left" 属性不会产生任何效果。)具体可参阅W3C school
offsetLeft 是HTML DOM Element对象的一个属性,offsetLeft属性返回当前元素左上角相对于HTMLElement.offsetParent节点的左边界偏移的像素值。具体可参阅MDN.
当然,style.left返回的是带有"px"的 可读写字符串类型,offsetLeft返回的是只读的数字型,本文中的比较均是取style.left中的数字值。
代码示例
HTML代码:
<body>
<img src="images2/pikachu2.jpg" style="left: 0">
<button>btn</button>
</body>
CSS代码:
* {
padding: 0;
margin: 0;
}
img {
position: relative;
margin-left: 300px;
}
JS代码:
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)
})
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><img src="images2/pikachu2.jpg"></div>
</body>
js部分代码不变。
结论
本文所讨论的情况下,当前元素的margin-left属性若已设值,则style.left与offsetLeft在数值上不等,否则是相等的。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!