【前端学习——js篇】11.元素可见区域

具体见:https://github.com/febobo/web-interview

11.元素可见区域

①offsetTop、scrollTop

offsetTop,元素的上外边框至包含元素的上内边框之间的像素距离,其他offset属性如下图所示:

下面再来了解下clientWidthclientHeight

  • clientWidth:元素内容区宽度加上左右内边距宽度,即clientWidth = content + padding
  • clientHeight:元素内容区高度加上上下内边距高度,即clientHeight = content + padding

这里可以看到client元素都不包括外边距

最后,关于scroll系列的属性如下:

  • scrollWidthscrollHeight 主要用于确定元素内容的实际大小

  • scrollLeftscrollTop 属性既可以确定元素当前滚动的状态,也可以设置元素的滚动位置

    • 垂直滚动 scrollTop > 0
    • 水平滚动 scrollLeft > 0
  • 将元素的 scrollLeftscrollTop 设置为 0,可以重置元素的滚动位置

  • 上述属性都是只读的,每次访问都要重新开始


判断页面触底我们需要先了解一下下面几个属性:

  • scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值
  • clientHeight:它是一个定值,表示屏幕可视区域的高度;
  • scrollHeight:页面不能滚动时也是存在的,此时scrollHeight等于clientHeight。scrollHeight表示body所有元素的总长度(包括body元素自身的padding)

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

在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如:

  • 图片的懒加载
  • 列表的无限滚动
  • 计算广告元素的曝光情况
  • 可点击链接的预加载
②实现方式

公式如下:

也就是元素距上外边框的距离 - 滚动视窗距window顶部的距离 ,是否超过了视窗高度。

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

属性对应的关系图如下所示:

当页面发生滚动的时候,topleft属性值都会随之改变。

如果一个元素在视窗之内的话,那么它一定满足下面四个条件:

  • 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);
案例

例子创建了一个十万个节点的长列表,当节点滚入到视窗中时,背景就会从红色变为黄色。

<body><div class="container"></div>
</body>
    .container {display: flex;flex-wrap: wrap;}.target {margin: 5px;width: 20px;height: 20px;background: red;}

首先插入100000个div

	const container = document.querySelector(".container");// 插入 100000 个 <div class="target"></div>function createTargets() {const htmlString = new Array(100000).fill('<div class="target"></div>').join("");container.innerHTML= htmlString;}

判定target是否在视窗中,element是传入的target

 function isInviewPort(element){const viewWidth = window.innerWidth || document.document.clientWidth;const viewHeigth = window.innerHeight || document.documentElement.clientWidth;const { top,right,bottom,left} = element.getBoundingClientRect();return top >= 0 && left >=0 && right <= viewWidth && bottom <= viewHeigth;}

绑定滑轮事件

 this.addEventListener('scroll',() =>{console.log("scroll!");const target = document.querySelectorAll('.target')for(const element of target){if(isInviewPort(element)){element.style =  "background-color:yellow"}else{element.style =  "background-color:red"}}})

可以看到,没当滑动就会把所有target,依次传入isInviewPort,若在视窗中则改变颜色为黄色,否则改为红色。

通过上面的方法基本实现要求,但是有明显的卡顿,原因在于我们绑定了scroll事件,scroll事件伴随了大量的计算,会造成资源方面的浪费。

下面试试观察者的方法,首先创建一个观察者,然后给每个target进行绑定。

 const observer = new IntersectionObserver(getYellow, { threshold: 1.0 });const target = document.querySelectorAll('.target')for (const element of target) {observer.observe(element)}

最后使用getYellow回调函数实现对背景颜色改变。

 function getYellow(entries, observer) {for (const entry of entries) {let element = entry.target// console.log(element);if (isInviewPort(element)) {element.style = "background-color:yellow"} else {element.style = "background-color:red"}}}

还是有延迟,但是明显好很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/288779.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑长周期供需不平衡风险的新型电力系统规划方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

codesys通过moudbus TCP连接西门子1214c,西门子做客户端

思路在codesys中发送数据到西门子&#xff0c;西门子原封不动的将数据传回。 1.首先配置codesys; 我设置了500个&#xff0c;但是好像发不这么多&#xff0c;只能120多个。因为什么来我忘了。但是这里不影响。 2.配置映射&#xff1a; 3.写代码 PROGRAM PLC_PRG VARarySendDa…

生产调度问题分类——机器视角

获取更多资讯&#xff0c;赶快关注上面的公众号吧&#xff01; 文章目录 单机调度并行机调度流水车间调度作业车间调度柔性作业车间开放车间总结 生产调度问题是实际工作中广泛存在的运筹学问题&#xff0c;可以描述为“给定若干加工任务&#xff0c;根据已有的生产条件&#…

JavaWeb学习笔记01

一、教程简介 全新JAVAWEB&#xff08;里程碑版&#xff09; 一套更适合后端工程师学习的WEB教程 All in Java 1、后端 ① Spring全家桶及微服务框架 ② 高性能数据库和消息组件 ③ Web攻击防护安全控制手段 ④ 其他第三方SDK生态环境 ...... 2、前端 ① 视图三大件&…

C是用什么语言写出来的?

C是用什么语言写出来的? C语言的起源和发展是一个迭代过程&#xff1a; 1. 最初的C语言编译器的开发始于对B语言的改进。B语言是由Ken Thompson设计的&#xff0c;它是基于BCPL语言简化而来的。在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 C语言的…

Sublime 彻底解决中文乱码

1. 按ctrl&#xff0c;打开Console&#xff0c;输入如下代码&#xff1a; import urllib.request,os; pf Package Control.sublime-package; ipp sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHand…

16:00面试,16:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

07_Response

文章目录 案例&#xff08;请求分发案例&#xff09; Response响应行响应头响应体特殊响应头refreshContent-typeContent-dispositionlocation 案例&#xff08;登录案例&#xff09; 案例&#xff08;请求分发案例&#xff09; 场景&#xff1a;有多个请求 Http://localhost:…

逐步学习Go-并发通道chan(channel)

概述 Go的Routines并发模型是基于CSP&#xff0c;如果你看过七周七并发&#xff0c;那么你应该了解。 什么是CSP&#xff1f; "Communicating Sequential Processes"&#xff08;CSP&#xff09;这个词组的含义来自其英文直译以及在计算机科学中的使用环境。 CSP…

day 36 贪心算法 part05● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

一遍过。首先把区间按左端点排序&#xff0c;然后右端点有两种情况。 假设是a区间&#xff0c;b区间。。。这样排列的顺序&#xff0c;那么 假设a[1]>b[0],如果a[1]>b[1]&#xff0c;就应该以b[1]为准&#xff0c;否则以a[1]为准。 class Solution { public:static bo…

Android中运动事件的处理

1.目录 目录 1.目录 2.前言 3.程序演示 4.第二种程序示例 5.扩展 2.前言 触摸屏&#xff08;TouchScreen&#xff09;和滚动球&#xff08;TrackBall&#xff09;是 Android 中除了键盘之外的主要输入设备。如果需要使用触摸屏和滚动球&#xff0c;主要可以通过使用运动事…

渐变色x轴换行柱状图

// 系统上云率const optionBar {title: {text: 系统上云率,left: left,textStyle: {color: "#fff",fontSize: 14,fontWeight: 650,align: "center",},},color: [#32C5FF, #00F766, #EECB5F],grid: {top: 40,bottom: 0,},legend: { // 控制图例组件show: …

K8s Pod亲和性、污点、容忍度、生命周期与健康探测详解(上)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 在上一章节中&#xff0c;我们详细探讨了Pod的概念、创建、…

逐步学习Go-协程goroutine

参考&#xff1a;逐步学习Go-协程goroutine – FOF编程网 什么是线程&#xff1f; 简单来说线程就是现代操作系统使用CPU的基本单元。线程基本包括了线程ID&#xff0c;程序计数器&#xff0c;寄存器和线程栈。线程共享进程的代码区&#xff0c;数据区和操作系统的资源。 线…

数据结构——排序算法

1、排序的概念 排序是指的是将一组数据&#xff08;如数字、单词、记录等&#xff09;按照某种特定的顺序&#xff08;升序或降序&#xff09;进行排列的过程。排序算法是实现排序的程序或方法&#xff0c;它们在软件开发和数据处理中扮演着至关重要的角色。 排序算法可以根据…

servlet开发详解

一、什么是servlet&#xff0c;干什么用的&#xff1f;&#xff1f;&#xff1f; tomcat作为一个web服务器&#xff0c;也称作servlet容器。servlet只有放在web服务器中才能运行&#xff0c;不能独立运行。tomcat这个容器要做三件事&#xff1a;接收请求、处理请求和响应请求。…

文生视频大模型Sora的复现经验

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

java调用jacob进行文件转换ppt转pdf或者png

java调用jacob进行文件转换ppt转pdf或者png 前情提要 最近项目上&#xff0c;遇到一个复杂的ppt&#xff0c;最终要求是要将ppt每一页转成图片原本这个是不难&#xff0c;网上一搜一大堆案例&#xff0c;外加我本身也比较精通aspose&#xff0c;那还不是分分钟搞定。结果就是…

Healix Protocol 的 HLX 通证预售:医疗领域的未来展望

Healix Protocol推出 HLX 通证预售&#xff0c;将带来医疗领域的重要变革。通过其区块链技术&#xff0c;Healix Protocol致力于重新定义医疗服务的可及性与负担性&#xff0c;成为医疗行业的希望之光。该项目旨在增强透明度、可及性和效率&#xff0c;推动医疗体系向更加公平和…

Hadoop面试重点

文章目录 1. Hadoop 常用端口号2.Hadoop特点3.Hadoop1.x、2.x、3.x区别 1. Hadoop 常用端口号 hadoop2.xhadoop3.x访问HDFS 端口500709870访问 MR 执行情况端口80888088历史服务器1988819888客户端访问集群端口90008020 2.Hadoop特点 高可靠&#xff1a;Hadoop底层维护多个数…