判断一个元素是否在可视区域中
文章目录
- 一、用途
- 二、实现方式
- offsetTop、scrollTop
- 注意
- getBoundingClientRect
- Intersection Observer
- 创建观察者
- 传入被观察者
- 三、案例分析
- 参考文献

一、用途
可视区域即我们浏览网页的设备肉眼可见的区域,如下图

在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如:
- 图片的懒加载
- 列表的无限滚动
- 计算广告元素的曝光情况
- 可点击链接的预加载
二、实现方式
判断一个元素是否在可视区域,我们常用的有三种办法:
-
offsetTop、scrollTop
-
getBoundingClientRect
-
Intersection Observer
offsetTop、scrollTop
offsetTop,元素的上外边框至包含元素的上内边框之间的像素距离,其他offset属性如下图所示:

下面再来了解下clientWidth、clientHeight:
clientWidth:元素内容区宽度加上左右内边距宽度,即clientWidth = content + paddingclientHeight:元素内容区高度加上上下内边距高度,即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.offsetTopconst scrollTop = document.documentElement.scrollTopconst top = offsetTop - scrollTopreturn 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);
}
Intersection Observer
Intersection Observer 即重叠观察者,从这个命名就可以看出它用于判断两个元素是否重叠,因为不用进行事件的监听,性能方面相比getBoundingClientRect会好很多
使用步骤主要分为两步:创建观察者和传入被观察者
创建观察者
const options = {// 表示重叠面积占被观察者的比例,从 0 - 1 取值,// 1 表示完全被包含threshold: 1.0, root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素
};const callback = (entries, observer) => { ....}const observer = new IntersectionObserver(callback, options);
通过new IntersectionObserver创建了观察者 observer,传入的参数 callback 在重叠比例超过 threshold 时会被执行`
关于callback回调函数常用属性如下:
// 上段代码中被省略的 callback
const callback = function(entries, observer) { entries.forEach(entry => {entry.time; // 触发的时间entry.rootBounds; // 根元素的位置矩形,这种情况下为视窗位置entry.boundingClientRect; // 被观察者的位置举行entry.intersectionRect; // 重叠区域的位置矩形entry.intersectionRatio; // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算)entry.target; // 被观察者});
};
传入被观察者
通过 observer.observe(target) 这一行代码即可简单的注册被观察者
const target = document.querySelector('.target');
observer.observe(target);
三、案例分析
实现:创建了一个十万个节点的长列表,当节点滚入到视窗中时,背景就会从红色变为黄色
Html结构如下:
<div class="container"></div>
css样式如下:
.container {display: flex;flex-wrap: wrap;
}
.target {margin: 5px;width: 20px;height: 20px;background: red;
}
往container插入1000个元素
const $container = $(".container");// 插入 100000 个 <div class="target"></div>
function createTargets() {const htmlString = new Array(100000).fill('<div class="target"></div>').join("");$container.html(htmlString);
}
这里,首先使用getBoundingClientRect方法进行判断元素是否在可视区域
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;
}
然后开始监听scroll事件,判断页面上哪些元素在可视区域中,如果在可视区域中则将背景颜色设置为yellow
$(window).on("scroll", () => {console.log("scroll !");$targets.each((index, element) => {if (isInViewPort(element)) {$(element).css("background-color", "yellow");}});
});
通过上述方式,可以看到可视区域颜色会变成黄色了,但是可以明显看到有卡顿的现象,原因在于我们绑定了scroll事件,scroll事件伴随了大量的计算,会造成资源方面的浪费
下面通过Intersection Observer的形式同样实现相同的功能
首先创建一个观察者
const observer = new IntersectionObserver(getYellow, { threshold: 1.0 });
getYellow回调函数实现对背景颜色改变,如下:
function getYellow(entries, observer) {entries.forEach(entry => {$(entry.target).css("background-color", "yellow");});
}
最后传入观察者,即.target元素
$targets.each((index, element) => {observer.observe(element);
});
可以看到功能同样完成,并且页面不会出现卡顿的情况
参考文献
- https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
- https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
相关文章:
判断一个元素是否在可视区域中
文章目录 一、用途二、实现方式offsetTop、scrollTop注意 getBoundingClientRectIntersection Observer创建观察者传入被观察者 三、案例分析 参考文献 一、用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标…...
【Monero】Wallet RPC | Wallet CLI | 门罗币命令行查询余额、种子、地址等命令方法教程
ubuntu22.04 首先在运行daemon,详细安装运行教程可参考:The Monero daemon (monerod) ./monerodWallet CLI run ./monero-wallet-cli如果还没有钱包就根据提示创建钱包即可 输入密码 查询余额 balance查询种子 seed其他可执行命令操作࿱…...
FPGA----ZCU106的petalinux 2019.1使用USB传输数据
1、实际项目中需要用到开发板的串口进行数据交互,之前讲的几节只是启动了网口(如下链接)。因此,本次给大家带来的官方自带串口例程的使用方法,本文的vivado工程和下述连接一样,PL端什么配置都没有。 FPGA-…...
备考ICA----Istio实验10---为单个主机配置TLS Istio Ingress Gateway实验
备考ICA----Istio实验10—为单个主机配置 TLS Istio Ingress Gateway实验 1. 环境准备 部署httpbin kubectl apply -f istio/samples/httpbin/httpbin.yaml 2. 证书生成 2.1 生成根证书 生成根证书keyfile和crt文件 mkdir example_certs_root openssl req -x509 -sha256 …...
【4】单链表(有虚拟头节点)
【4】单链表(有虚拟头节点) 1、虚拟头节点2、构造方法3、node(int index) 返回索引位置的节点4、添加5、删除6、ArrayList 复杂度分析(1) 复杂度分析(2) 数组的随机访问(3) 动态数组 add(E element) 复杂度分析(4) 动态数组的缩容(5) 复杂度震荡 7、单链…...
html第二次作业
骨架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initi…...
Android客户端自动化UI自动化airtest从0到1搭建macos+脚本设计demo演示+全网最全最详细保姆级有步骤有图
iOS客户端自动化UI自动化airtest从0到1搭建macosdemo演示-CSDN博客 一、基础环境 1. 安装jdk 选择jdk8 如果下载高版本 可能不匹配会失败 下载.dmg文件 苹果电脑 | macOS | jdk1.8 | 环境变量配置_jdk1.8 mac-CSDN博客 Java Downloads …...
基于单片机的自动浇灌系统的设计
本文设计了一款由单片机控制的自动浇灌系统。本设计的硬件电路采用AT89C51单片机作为主控芯片,采用YL-69土壤湿度传感器检测植物的湿度。通过单片机将采集湿度值与设定值分析处理后,控制报警电路和水泵浇灌电路的开启,从而实现植物的自动浇灌。 1 设计目的 随着生活水平的…...
WebStorm 与 VSCode 对比分析
WebStorm 与 VSCode 对比分析 1. 引言 简述WebStorm和VSCode的普及和重要性 WebStorm和Visual Studio Code(VSCode)是当前最受欢迎的代码编辑器之一,它们在现代软件开发中扮演着至关重要的角色。WebStorm,由JetBrains开发,是一个强大的IDE,特别受JavaScript开发者的欢…...
git命令-项目使用
项目中用到的git命令,记录下来,后续项目可以直接用 配置命令 一次性设置: git config --global user.name "Your Name" git config --global user.email "youremailaddress.com"git config --global alias.pl "pu…...
python安装删除以及pip的使用
目录 你无法想象新手到底会在什么地方出问题——十二个小时的血泪之言! 问题引入 python modify setup 隐藏文件夹 环境变量的配置 彻底删除python 其他零碎发现 管理员终端 删不掉的windous应用商店apps 发现问题 总结 你无法想象新手到底会在什么地方…...
7、鸿蒙学习-共享包概述
HarmonyOS提供了两种共享包,HAR(Harmony Archive)静态共享包,和HSP(Harmony Shared Package)动态共享包。 HAR与HSR都是为了实现代码和资源的共享,都可以包含代码、C库、资源和配置文件…...
亚马逊测评新策略:解决底层环境防关联,提升下单成功率
对于做测评的环境系统,确保稳定性和成功率是非常重要的。市面上有各种环境方案,如虚拟机、模拟机、gcs、云手机、VPS等。然而,这些方案不仅成本高,而且成功率很低。因此,一个好的环境系统是成功的基础。 亚马逊平台的…...
容器和注解开发
1.创建容器的两种方式 //1.加载类路径下的配置文件//ApplicationContext ctx new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从文件系统下加载配置文件(绝对路径) ApplicationContext ctx new FileSystemXmlApplicationContex…...
有趣且重要的JS知识合集(21)浏览器内置对象讲解之Dom篇
1、Dom 1.1、概念 Document Object Model(文档对象模型), 整个WEB页面, 所有的Dom元素都在Document整个文档里。DOM就是把整个文档页面当做一个对象进行操作, document 下 包含了 根据 html 创建 的 Dom 对象, 这个DOM对象, 以树形结构展示, 即DOM树 …...
3.两数相加 - 链表
文章目录 题目简介题目解答代码: 题目链接 大家好,我是晓星航。今天为大家带来的是 两数相加 相关的讲解!😀 题目简介 题目解答 通过题目给的第一个示例来解析 图解如下: l1的2和l2的5首先相加变为7 这里相加结果为7…...
iptables 与 firewalld 防火墙
iptables iptables 是一款基于命令行的防火墙策略管理工具 四种防火墙策略: ACCEPT(允许流量通过) 流量发送方会看到响应超时的提醒,但是流量发送方无法判断流量是被拒绝,还是接收方主机当前不在线 REJECT(…...
Taskflow:异步任务(Asynchronous Tasking)
简单使用 tf::Executor 提供了异步执行Task的操作tf::Executor::async,并返回Future,用于保留该函数调用的结果。 #include <taskflow/taskflow.hpp>void print_str(char const* str) {std::cout << str << std::endl; }int main() …...
学习鸿蒙基础(9)
目录 一、鸿蒙国际化配置 二、鸿蒙常用组件介绍 三、鸿蒙像素单位介绍 四、鸿蒙布局介绍 1、Row与Column线性布局 2、层叠布局-Stack 3、弹性布局 4、栅格布局 5、网格布局 一、鸿蒙国际化配置 base目录下为默认的string。en_US对应美国的。zh_CN对应中国的。新增一个s…...
spring boot的小数位丢失.00 或者.0
1、背景 在使用spring boot时,前端的界面展示的数据是2 ,在数据库中存储的是小数。但是导出Excel的时候数据是 2.00 。奇了怪了为啥会不一样,数据都是一样的没有做过处理。 2、排查问题 经过层层的debug 发现数据库返回的数据是2.00&#x…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
