判断元素是否在可视区域中

1,562 阅读2分钟

摘要

如下图所示,当一个元素的内容content超出其可视范围client之后,就会出现滚动条,而页面中的el元素可能会随着滚动条滚动移出可视区之外,这时我们经常需要去判断一个元素是否在可视区域中。 这里介绍两种方法进行判断,此文以竖直方向的滚动为例。

image.png

法一:使用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的顶部

image.png

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对象,其提供了元素的大小及其相对于视口的位置。

image.png

同样满足上述临界值即可进行判断。

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
    }
}
​