JS判断元素是否在可视区域技巧详解
作者:爱划水de鲸鱼哥 时间:2024-04-22 12:56:23
前言
在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如:
图片的懒加载
列表的无限滚动
计算广告元素的曝光情况
可点击链接的预加载
实现方式
判断一个元素是否在可视区域,我们常用的有offsetTop、scrollTop和getBoundingClientRect
offsetTop、scrollTop
offsetTop
,元素的上外边框至包含元素的上内边框之间的像素距离,其他offset
属性如下图所示:
下面再来了解下clientWidth
、clientHeight
:
clientWidth
:元素内容区宽度加上左右内边距宽度,即clientWidth = content + padding
clientHeight
:元素内容区高度加上上下内边距高度,即clientHeight = content + padding
这里可以看到client
元素都不包括外边距
最后,关于scroll
系列的属性如下:
scrollWidth
和scrollHeight
主要用于确定元素内容的实际大小scrollLeft
和scrollTop
属性既可以确定元素当前滚动的状态,也可以设置元素的滚动位置垂直滚动
scrollTop > 0
水平滚动
scrollLeft > 0
将元素的
scrollLeft
和scrollTop
设置为 0,可以重置元素的滚动位置
注意
上述属性都是只读的,每次访问都要重新开始
下面再看看如何实现判断:
公式如下:
el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
代码实现:
function isInViewPortOfOne (el) {
// viewPortHeight 兼容所有浏览器写法
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const offsetTop = el.offsetTop
const scrollTop = document.documentElement.scrollTop
const top = offsetTop - scrollTop
return top <= viewPortHeight
}
getBoundingClientRect
返回值是一个 DOMRect
对象,拥有left
, top
, right
, bottom
, x
, y
, width
, 和 height
属性
const target = document.querySelector('.target');
const clientRect = target.getBoundingClientRect();
console.log(clientRect);
// {
// bottom: 556.21875,
// height: 393.59375,
// left: 333,
// right: 1017,
// top: 162.625,
// width: 684
// }
属性对应的关系图如下所示:
当页面发生滚动的时候,top
与left
属性值都会随之改变
如果一个元素在视窗之内的话,那么它一定满足下面四个条件:
top 大于等于 0
left 大于等于 0
bottom 小于等于视窗高度
right 小于等于视窗宽度
实现代码如下:
function isInViewPort(element) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
const {
top,
right,
bottom,
left,
} = element.getBoundingClientRect();
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
);
}
来源:https://juejin.cn/post/7178480410223968312
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
JavaScript内置对象math,global功能与用法实例分析
MySQL慢查日志的开启方式与存储格式详析
![](https://img.aspxhome.com/file/2023/8/75638_0s.png)
MYSQL大表加索引的实现
![](https://img.aspxhome.com/file/2023/0/76360_0s.png)
python DataFrame 取差集实例
mysql5.5 master-slave(Replication)主从配置
Python摸鱼神器之利用树莓派opencv人脸识别自动控制电脑显示桌面
![](https://img.aspxhome.com/file/2023/1/97531_0s.jpg)
通过Python实现猜灯谜游戏的示例代码
![](https://img.aspxhome.com/file/2023/9/104979_0s.jpg)
利用SQL Server复制技术实现数据同步更新
《JavaScript语言精粹》译者序及样章试读
合并网页中的多个script引用实现思路及代码
两个table之间相互移动数据
微信小程序跳转到其他网页(外部链接)的实现方法
![](https://img.aspxhome.com/file/2023/1/136461_0s.png)
Vue.js监听select2的值改变进行查询方式
利用python清除移动硬盘中的临时文件
![](https://img.aspxhome.com/file/2023/7/67797_0s.jpg)
基于python实现把json数据转换成Excel表格
Python OpenCV图像指定区域裁剪的实现
在JavaScript中获取请求的URL参数
go reflect要不要传指针原理详解
![](https://img.aspxhome.com/file/2023/4/134084_0s.png)