JQ的offset().top与js的offsetTop区别详解
⼀、前⾔
send sth for sb和send sth to sb
最近在做⼀个图⽚懒加载的插件,就纵轴(Y轴)⽽⾔,我需要时时获取图⽚的上偏移量,好判断是否已进⼊视图区域,⽽我所理解的是offsetTop应该是跟offset().top⼀样的,然后陷⼊了因为不了解它们区别,⽽带来BUG的死坑。这⾥通过实验整理,做个清晰好懂的笔记,如果你也想弄清,建议复制我的代码跟着操作,印象会更为深刻。
⼆、offset().top与offsetTop什么意思?它们都是相对谁的上偏移量?
offset().top是JQ的⽅法,需要引⼊JQ才能使⽤,它获取的是你绑定元素上边框相对于⽂档顶端的偏移量,我们可以把⽂档理解成⼀幅图,这幅图包含了html,html内容越多图越长,浏览⽹页时,就是透过透明的玻璃(视窗)在看这幅画。
offsetTop是原⽣JS的⽅法,它获取的是你绑定元素上边框相对离⾃⼰最近且position属性为⾮static的祖先元素的偏移量(后⾯会具体解释)。
区别⼀:offset().top与offsetTop偏移量参照对象不同,offset().top始终是html,⽽offsetTop参照的对象是可变的。
⼤家可以先拷贝下⾯代码:
html部分
<ul class="contain">
<li><div></div></li>
  <li><div></div></li>
<li><div></div></li>
<li><div></div></li>
</ul>
css部分
body{
position:relative;
padding:0;
margin:0;
/* display: table; */
}
.contain{
list-style: none;
height: 1000px;
width: 800px;
overflow: auto;
margin-top:200px;
background-color:#ebc38d;
}
.contain>li{
margin-bottom: 10px;
}
.contain>li>div{
background-color: #e4393c;
width: 300px;
height: 400px;
}
渐变发型男士js部分
var ul = document.querySelector(".contain");
var div = document.querySelectorAll("div")[0];
function demo() {
css的关联选择器var top1 = div.offsetTop;//第⼀个div的上偏移量
var top2 = $(div).offset().top;//第⼀个div的上偏移量
var top3 =ul.scrollTop;//ul⾃⼰的滚动条已滚动的距离,默认是0,往下滚动慢慢变⼤
console.log(top2, top1, top3);
}
demo()
ul.addEventListener("scroll", demo);
html⾃⼰⽣成补全,记得引⼊JQ,这⾥提供⼀个静态资源库,直接复制JQ地址引⼊就可以了。
在css中我为ul加了⼀个上边距为200px,先不解决上边距坍塌的问题,这会导致整个body区域距离页头有200px的空⽩区域,以⽅便区分body和html,如下图html范围和body范围:
这是html的范围
这是body的范围,很明显⽐html要矮出200px的空⽩区域,因为html没有设置上margin,可以说⽂档和html范围是相同的:
打开控制台,我们可以看到输出了200,0,0;
第⼀个200:offset().top的值是第⼀个div上边界相对html的上偏移量,因为有200px的margin,所以是200;
第⼆个0:offsetTop的值第⼀个div上边界相对body的上偏移量,因为从div往上,第⼀个position属性为⾮static的(relative,absolute,fixed其⼀)的祖先元素是body,所以相对body。
第三个0:scrollTop的值容器ul滚动条滚动的距离,因为默认没有滚动,所以是0;
socket调webservice
我们来做下改变,将body的position:relative属性移动到html上,其它不变,像这样:
我们可以看到此时输出:200,200,0;
第⼀个200:offset().top的值还是第⼀个div相对html的上偏移量,因为margin的问题。
第⼆个200:offsetTop的值验证了我们之前的概念,offsetTop的参照对象是第⼀个position不为static的祖先元素,此时被我们修改成了html;
第三个0:容器ul的滚动条距离。
我们将body的display:table的注释去掉,将html的position属性去掉并还给body。其它不变,像这样,毕竟布局中上margin坍塌本来就不合理:
此时的body已经跟html范围相同,不存在200px空⽩区域,虽然offsetTop参照的是body,offset().top参照的是html,但从两个参照对象的上边界⽽⾔,可以理解为参照的是统⼀对象。可以看到控制台还是输出200,200,0。
相同点:当⽆滚动条且offsetTop与offset().top参照对象相同时,它们获取的值相同。
区别⼆:offsetTop获取的偏移量不随滚动条滚动变化,但offset().top跟这滚动条变化position和location的区别
我们尝试滚动ul的滚动条,观察输出值的变化
可以看到offset().top的值随着滚动条滚动越变越⼩,因为第⼀个div的上边界与html的上边界越来越近了。
⽽offsetTop的值从⼀开始的200⼀直就没变化,不受滚动条影响。
⽽ul的scrollTop也随着我们的滚动条往下拉,有了滚动距离,也在慢慢变⼤。很好理解不是吗?
三、猜测:offset().top = offsetTop - scrollTop
JQ能拿到变化的上偏移量,原⽣JS怎么拿这个变化的值呢?参照上⾯试验,scrollTop变⼤的同时,offset().top也在随之变⼩,只有 offsetTop恒定不变。
不⽤猜测了,⼤家将滚动输出打印的数字做个计算,很明显,第⼀个数字 = 第⼆个数字  - 第三个数字,就算offset().top为负数也⼀样遵守规则:
水泵电机是异步电机吗那我们可以得出这样⼀个规律:
当⼀个元素的offset().top与offsetTop的参照对象相同时,offset().top的值等于offsetTop的值减去scrollTop的值。
我们将body的display属性注释掉,像这样
很明显,因为margin坍塌的问题,body和html之间⼜多了200px的空⽩间隔区域,offset().top与offsetTop的参照对象这下就不同了,我们滚动滚动条可以看到规则就不适⽤了:
四、总结
offsetTop与offset().top相同点:
1.当⽆滚动条且offsetTop与offset().top参照对象相同时,它们获取的值相同。
offsetTop与offset().top不同点:
1.offset().top与offsetTop偏移量参照对象不同,offset().top始终是⽂档,⽽offsetTop参照的对象是可变的。
2.offsetTop获取的偏移量不随滚动条滚动变化,但offset().top随着滚动条变化(注意滚动监听的是⼀个有滚动条的元素,⽽不是window)
⼀个规律:
1.当⼀个元素的offset().top与offsetTop的参照对象相同时,offset().top = offsetTop - scrollTop
还是建议⼤家能照着练⼀遍,要不了多少时间,印象也会更深刻,也欢迎⼤家的补充和纠正,毕竟我也可能有理解错误的地⽅。
另外,本⽂中的例⼦是元素有滚动条的情况,如果监听的是window的滚动条,这个结论就不适⽤,不过我们可以利⽤JS的getBoundingClientRect解决,想知道getBoundingClientRect与offset().top以及offsetTop有何区别吗?欢迎阅读博主另⼀篇博客:
转载请标明出处,谢谢。好困...........

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。