摘要
如下图所示,当一个元素的内容content超出其可视范围client之后,就会出现滚动条,而页面中的el元素可能会随着滚动条滚动移出可视区之外,这时我们经常需要去判断一个元素是否在可视区域中。 这里介绍两种方法进行判断,此文以竖直方向的滚动为例。
法一:使用scrollTop滚动条的滚动位置进行判断
在判断之前,首先弄清楚一些基本的概念。
获取元素自身的高度
clientHeight
= height + padding
offsetHeight
= height + padding + border
scrollHeight
= height + padding
获取偏移量
clientTop
:该元素对象的上边框宽度
offsetTop
:该元素上外边框相对于 offsetParent 节点顶部边界的偏移像素值。(offsetParent元素是一个指向最近的(指包含层级上的最近)包含该元素的定位元素或者最近的元素。)
scrollTop
:页面利用滚动条滚动到下侧时,隐藏在滚动条上侧的页面的宽度(滚动条在父元素身上,所以判断滚动的距离应该在父元素上判断)
知道基本概念后,我们来对其进行分析,元素在页面滚动消失不见可以分为两种情况,一种是向上滚动,一种是向下滚动。
1)滚动条往下滚,页面会向上走,el元素跟着页面一起向上
此时scrollTop不断增大,offsetTop+el元素自身高度-scrollTop = el底部到client的顶部高度
当这个距离等于0的时候,表示el的底部已经向上滚动到了client的顶部
2)滚轮往上滚,页面向下移动,el元素跟着页面一起向下
此时scrollTop不断减小,offsetTop - client元素自身高度 - scrollTop = el顶部到client的底部高度
当这个距离等于0的时候,表示el的顶部已经向下滚动到了client的底部
因此,想要判断el元素是否在页面中,就需要判断这两个临界值,当满足 el元素下边界 > client上边界
且 el元素上边界 < client的下边界
这两个条件时,元素在可视区域中,代码如下:
function isInView(el,client){
let scrollTop = client.scrollTop,
clientTop = el.offsetTop,
elHeight = el.offsetHeight,
clientHeight = client.offsetHeight
if (scrollTop < clientTop + elHeight && scrollTop > clientTop - clientHeight) {
return true
}
}
法二:使用getBoundingClientRect
Element.getBoundingClientRect()
方法返回一个DOMRect对象,其提供了元素的大小及其相对于视口的位置。
同样满足上述临界值即可进行判断。
function isInView(el,client){
let rect = el.getBoundingClientRect(),
elTop = rect.top, // el顶部距离视口的高度
elBottom = rect.bottom, // el底部距离视口的高度
elHeight = rect.height, // el元素自身高度
clientHeight = client.offsetHeight, //client视口高度
if (elBottom > 0 && elTop < clientHeight) {
return true
}
}