008-如何判断一个元素是否在可视区域中
实现方式
判断一个元素是否在可视区域内,我们一般使用以下几种方法:
- offsetTop、scrollTop
- getBoundingClientRect
- Intersection Observer
offsetTop、scrollTop
offsetTop
:返回当前元素的外边框至父元素的上内边框的像素距离scrollTop
:一个元素的scrollTop
值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的scrollTop
值为0
再了解下以下几个方法:
clientWidth
:元素内容区宽度加左右内边距宽度,即content + padding
clientHeight
:元素内容区高度加上下内边距宽度,即content + padding
scrollWidth
:是一个元素内容宽度的度量,包括由于overflow
溢出而在屏幕上不可见的内容scrollHeight
:是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容
计算公式如下:
// 满足下面判断就在可视区域内
el.offsetTop - document.documentElement.scrollTop <= viewHeight
function viewHeight() {
// 兼容性写法
return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
getBoundingClientRect
getBoundingClientRect()
方法返回一个 DOMRect
对象,其提供了元素的大小及其相对于视口的位置。
返回值是一个 DOMRect
对象,是包含整个元素的最小矩形(包括 padding
和 border-width
)。该对象使用 left
、top
、right
、bottom
、x
、y
、width
和 height
这几个以像素为单位的只读属性描述整个矩形的位置和大小。除了 width
和 height
以外的属性是相对于视图窗口的左上角来计算的。
如下图说明:
因此判断一个元素是否在可视区域内,需要满足以下条件:
top >= 0
left >= 0
bottom <= viewHeight
right <= viewWidth
实现代码如下:
function isInViewPort(element) {
const target = document.querySelector('div')
const viewWidth = window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth
const viewHeight = window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight
const {
top,
right,
bottom,
left,
} = target.getBoundingClientRect()
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
)
}
IntersectionObserver
IntersectionObserver()
构造器创建并返回一个 IntersectionObserver
对象。 如果指定 rootMargin
则会检查其是否符合语法规定,检查阈值以确保全部在 0.0
到 1.0
之间,并且阈值列表会按升序排列。如果阈值列表为空,则默认为一个 [0.0]
的数组。
语法如下:
var observer = new IntersectionObserver(callback[, options])
var callback = function (entries, observer) {}
var options = {
root: document.querySelector('#id'),
rootMargin: '0px 0px 0px 0px',
threshold: 1.0,
}
通过 new IntersectionObserver
创建了观察者 observer
,传入的参数 callback
在重叠比例超过 threshold
时会被执行。
举个例子:
const target = document.querySelector('.target')
observer.observe(target)
应用场景
- 列表无限滚动
- 图片懒加载
- 可点击链接的预加载
- 计算广告元素的曝光情况
部分答案整理自网络资源