| 如何判断一个元素是否在可视区域中?
					当前位置:点晴教程→知识管理交流
					
					→『 技术文档交流 』
					
				 
 
 一、用途可视区域即我们浏览网页的设备肉眼可见的区域,如下图 
 在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如: 
 二、实现方式判断一个元素是否在可视区域,我们常用的有三种办法: 
 offsetTop、scrollTop
 
 下面再来了解下 
 这里可以看到 最后,关于 
 注意
 下面再看看如何实现判断: 公式如下: 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返回值是一个  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
// }属性对应的关系图如下所示: 
 当页面发生滚动的时候, 如果一个元素在视窗之内的话,那么它一定满足下面四个条件: 
 实现代码如下: 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
 使用步骤主要分为两步:创建观察者和传入被观察者 创建观察者const options = {
  // 表示重叠面积占被观察者的比例,从 0 - 1 取值,
  // 1 表示完全被包含
  threshold: 1.0, 
  root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素
};
const callback = (entries, observer) => { ....}
const observer = new IntersectionObserver(callback, options);通过 关于 // 上段代码中被省略的 callback
const callback = function(entries, observer) { 
    entries.forEach(entry => {
        entry.time;               // 触发的时间
        entry.rootBounds;         // 根元素的位置矩形,这种情况下为视窗位置
        entry.boundingClientRect; // 被观察者的位置举行
        entry.intersectionRect;   // 重叠区域的位置矩形
        entry.intersectionRatio;  // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算)
        entry.target;             // 被观察者
    });
};传入被观察者通过  const target = document.querySelector('.target');
observer.observe(target);三、案例分析实现:创建了一个十万个节点的长列表,当节点滚入到视窗中时,背景就会从红色变为黄色 
 <div class="container"></div> 
 .container {
    display: flex;
    flex-wrap: wrap;
}
.target {
    margin: 5px;
    width: 20px;
    height: 20px;
    background: red;
}往 const $container = $(".container");
// 插入 100000 个 <div class="target"></div>
function createTargets() {
  const htmlString = new Array(100000)
    .fill('<div class="target"></div>')
    .join("");
  $container.html(htmlString);
}这里,首先使用 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;
}然后开始监听 $(window).on("scroll", () => {
    console.log("scroll !");
    $targets.each((index, element) => {
        if (isInViewPort(element)) {
            $(element).css("background-color", "yellow");
        }
    });
});通过上述方式,可以看到可视区域颜色会变成黄色了,但是可以明显看到有卡顿的现象,原因在于我们绑定了 下面通过 首先创建一个观察者 const observer = new IntersectionObserver(getYellow, { threshold: 1.0 });
 function getYellow(entries, observer) {
    entries.forEach(entry => {
        $(entry.target).css("background-color", "yellow");
    });
}最后传入观察者,即 $targets.each((index, element) => {
    observer.observe(element);
});可以看到功能同样完成,并且页面不会出现卡顿的情况 转自https://www.cnblogs.com/smileZAZ/p/18216096 该文章在 2025/10/14 15:21:57 编辑过 | 关键字查询 相关文章 正在查询... |