前端必知:如何判断元素出现在视口内(性能优化涉及)

Posted 清颖~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端必知:如何判断元素出现在视口内(性能优化涉及)相关的知识,希望对你有一定的参考价值。

要检测一个元素是否可见或者两个元素是否相交的需求场景有这些:

  • 图片懒加载——当图片滚动到可见时才进行加载
  • 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
  • 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
  • 在用户看见某个区域时执行任务或播放动画

1. 知识铺垫:确定浏览器窗口的尺寸

有三种方法能够确定浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)。

对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari:

window.innerHeight - 浏览器窗口的内部高度
window.innerWidth - 浏览器窗口的内部宽度

对于 Internet Explorer 8、7、6、5:

document.documentElement.clientHeight
document.documentElement.clientWidth    

或者混杂模式(没有)下:

document.body.clientHeight
document.body.clientWidth

实用的 javascript 方案(涵盖所有浏览器):

var w=window.innerWidth
	|| document.documentElement.clientWidth
	|| document.body.clientWidth;

var h=window.innerHeight
	|| document.documentElement.clientHeight
	|| document.body.clientHeight;

一些其他 Window 方法:

window.open() - 打开新窗口
window.close() - 关闭当前窗口
window.moveTo() - 移动当前窗口
window.resizeTo() - 调整当前窗口的尺寸

scrollTop(): 方法设置或返回被选元素的垂直滚动条位置。
当用于返回位置时:
该方法返回第一个匹配元素的滚动条的垂直位置。

当用于设置位置时:
该方法设置所有匹配元素的滚动条的垂直位置。
scrollHeight属性: 滚动的总高度,指的是包含滚动内容的元素大小(元素内容的总高度)。
window.scrollBy(x,y):x轴,y轴的一次滚动的距离。

2. 判断元素是否出现在视口:

方法一:offsetTop - scrollTop <= 视口高度

function isInViewPortOfOne (element) 
  // 获取可视窗口的高度。兼容所有浏览器
  const screenHeight = window.innerHeight || document.documentElement.clientHeight
  	 || document.body.clientHeight;
  // 获取滚动条滚动的高度
  const scrollTop = document.documentElement.scrollTop;
  // 获取元素偏移的高度。就是距离可视窗口的偏移量。
  const offsetTop = element.offsetTop;
  // 加100是为了提前加载
  return offsetTop - scrollTop <= screenHeight + 100;

方法二:getBoundingClientReact()

getBoundingClientReact() 返回值是一个 DOMRect对象,拥有left, top, right, bottom, x, y, width, height属性。
公式: el.getBoundingClientReact().top <= viewPortHeight

function isInViewPortOfTwo (el) 
    const screenHeight = window.innerHeight || document.documentElement.clientHeight
    	 || document.body.clientHeight;
    const top = el.getBoundingClientRect() && el.getBoundingClientRect().top;
    return top  <= screenHeight + 100;

方法三:IntersectionObserver

// io 为 IntersectionObserver对象 - 由IntersectionObserver()构造器创建
 var io = new IntersectionObserver((entries) => 
   // entries 为 IntersectionObserverEntry对像数组
   entries.forEach((item) => 
     // item 为 IntersectionObserverEntry对像
     // isIntersecting是一个Boolean值,判断目标元素当前是否可见
     if (item.isIntersecting) 
       // div 可见时 进行相关操作
       console.log(item.target.innerText);
       io.unobserve(item.target); //停止监听该div DOM节点
     
   );
 ); // 不传options参数,默认根元素为浏览器视口
const divArr = [...document.querySelectorAll(".item")];
 divArr.forEach((div) => io.observe(div)); // 遍历监听所有div DOM节点

更多 IntersectionObserver 介绍,参见:

  1. https://juejin.cn
  2. MDN

以上是关于前端必知:如何判断元素出现在视口内(性能优化涉及)的主要内容,如果未能解决你的问题,请参考以下文章

判断元素是否在视口和元素相交

Cassandra性能优化--如何提升交叉分区查询性能

js前端性能优化之函数节流和函数防抖

WEB前端性能优化之二——css优化

前端性能优化:雅虎14条优化规则

web前端性能优化——图片加载的优化