jquery的offset().top详解

来源:网络 文章列表 2019-06-19 8
offset().top是JQ的方法,需要引入jquery才能使用,它获取的是你绑定元素上边框相对于html上边界的偏移量。offset().top参展对象始终是html

最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因为不了解它们区别,而带来BUG的死坑。这里通过实验整理,做个清晰好懂的笔记,如果你也想弄清,建议复制我的代码跟着操作,印象会更为深刻。

offset().top特点

1、offset().top是JQ的方法,需要引入jquery才能使用,它获取的是你绑定元素上边框相对于html上边界的偏移量。

2、offset().top参展对象始终是html

 

offset().top 对比 offsetTop

offsetTop 是原生JS的方法,它获取的是你绑定元素上边框相对离自己最近且position属性为非static的祖先元素的偏移量(后面会具体解释)。

offsetTop参照的对象是可变的

 

示例对比:

offset().top始终是html

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() {
    var top1 = div.offsetTop;//第一个div的上偏移量
    var top2 = $(div).offset().top;//第一个div的上偏移量
    var top3 =ul.scrollTop;//ul自己的滚动条已滚动的距离,默认是0,往下滚动慢慢变大
    //我的猜测 top2 = top1 - top3;
    console.log(top2, top1, top3);
}

demo()
ul.addEventListener("scroll", demo);

在css中我为ul加了一个上边距为200px,先不解决上边距坍塌的问题,这会导致整个body区域距离页头有200px的空白区域,以方便区分body和html,如下图html范围和body范围:

这是html的范围

这是body的范围,很明显比html要矮出200px的空白区域:

打开控制台,我们可以看到输出了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;

我们来做下改变,将display:talbe的注释取消,同时将body的position:relative属性移动到html上,其它不变,像这样:

html{
	position: relative;
}
body{
	padding: 0;
	margin: 0;
}

我们可以看到此时输出: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{
	padding: 0;
	margin: 0;
	display: table;
	position: relative;
}

此时的body已经跟html范围相同,不存在200px空白区域,虽然offsetTop参照的是body,offset().top参照的是html,但从两个参照对象的上边界而言,可以理解为参照的是统一对象。

可以看到控制台还是输出200,200,0。

相同点:当无滚动条且offsetTop与offset().top参照对象相同时,它们获取的值相同。

区别二:offsetTop获取的偏移量不随滚动条滚动变化,但offset().top跟这滚动条变化

我们尝试滚动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属性注释掉,像这样

body{
	padding: 0;
	margin: 0;
	/*display: table;*/
	position: relative;
}

 

总结

offsetTop与offset().top相同点:

1.当无滚动条且offsetTop与offset().top参照对象相同时,它们获取的值相同。

offsetTop与offset().top不同点:

1.offset().top与offsetTop偏移量参照对象不同,offset().top始终是html,而offsetTop参照的对象是可变的。

2.offsetTop获取的偏移量不随滚动条滚动变化,但offset().top随着滚动条变化

一个规律:

1.当一个元素的offset().top与offsetTop的参照对象相同时,offset().top = offsetTop - scrollTop

还是建议大家能照着练一遍,要不了多少时间,印象也会更深刻,也欢迎大家的补充和纠正,毕竟我也可能有理解错误的地方。

版权声明

本站部分原创文章,部分文章整理自网络。如有转载的文章侵犯了您的版权,请联系站长删除处理。如果您有优质文章,欢迎发稿给我们!联系站长:
愿本站的内容能为您的学习、工作带来绵薄之力。

评论

  • 随机获取
点击刷新
精彩评论
关闭