vue怎么判断元素是否在可视区域

三种方法:1、利用offsetTop和scrollTop获取元素的位置,判断是否小于等于viewPortHeight(视图端口距离)即可。2、利用getBoundingClientRect()判断,语法“元素对象.getBoundingClientRect()”。3、利用IntersectionObserver判断,只需要检查指定元素和可视区域是否重叠即可。

vue怎么判断元素是否在可视区域

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

可视区域是什么

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

1.png

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

立即学习“前端免费学习笔记(深入)”;

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

判断元素是否在可视区域的三种方式

判断一个元素是否在可视区域,我们常用的有三种办法:

offsetTop、scrollTop

getBoundingClientRect

Intersection Observer

方法1、offsetTop、scrollTop

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

https://cdn.chuangxiangniao.com/2025/03/20250314065737768.png

下面再来了解下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 

登录后复制

代码实现:

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 

登录后复制

方法2:getBoundingClientRect

返回值是一个 DOMRect对象,拥有left, top, right, bottom, x, y, width, 和 height属性。【学习视频分享:vue视频教程、vue视频教程】

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

登录后复制

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

3.png

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

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

top 大于等于 0left 大于等于 0bottom 小于等于视窗高度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 

登录后复制

方法3: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回调函数常用属性如下:

// 上段代码中被省略的 callbackconst 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结构如下:

登录后复制

css样式如下:

.container {    display: flex;    flex-wrap: wrap;}.target {    margin: 5px;    width: 20px;    height: 20px;    background: red;}

登录后复制

往container插入1000个元素

const $container = $(".container");// 插入 100000 个 
function createTargets() {  const htmlString = new Array(100000)    .fill('
')    .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 

登录后复制

然后开始监听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);});

登录后复制可以看到功能同样完成,并且页面不会出现卡顿的情况

以上就是vue怎么判断元素是否在可视区域的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2924401.html

(0)
上一篇 2025年3月11日 18:56:32
下一篇 2025年2月24日 18:25:39

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • vue什么时候会出现白屏

    vue出现白屏的3种情况:1、把路由模式mode设置成history了;只需改为hash或者直接删除模式配置,如果非要用history的话,在服务端加一个覆盖所有情况的候选资源即可。2、打包后的dist目录下的文件引用路径不对,会因找不到文…

    2025年3月11日
    200
  • vue的key是什么

    在vue中,key是DOM对象的标识,是给每一个vnode的唯一id,也是diff的一种优化策略;可以根据key,更准确、 更快的找到对应的vnode节点。如果数据只做展示使用,可以使用index作为key;如果使用index作为key,而…

    2025年3月11日 编程技术
    200
  • vue的watch是做什么的

    在vue中,watch用于监听data里面的数据是否被修改,一旦修改就可以执行一些其他的操作。watch是vue内部提供的一个用于侦听功能的通用的方法,可响应数据的变化,通过特定的数据变化驱动一些操作。 本教程操作环境:windows7系统…

    2025年3月11日 编程技术
    200
  • vue路由模式有哪些

    vue路由模式有:1、hash模式,使用URL的hash值来作为路由,支持所有浏览器;其url路径会出现“#”字符。2、history模式,依赖于HTML5 API(旧浏览器不支持)和HTTP服务端配置,没有后台配置的话,页面刷新时会出现4…

    2025年3月11日
    200
  • 用vue框架有什么好处

    用vue的好处:1、Vue是组件化开发,减少代码的书写,使代码易于理解;2、可以对数据进行双向绑定;3、相比较传统的用超链接进行页面的切换与跳转,Vue使用的是路由,不用刷新页面;4、Vue是单页应用,加载时不用获取所有的数据和dom,提高…

    2025年3月11日
    200
  • vue缓存组件是什么意思

    在vue中,缓存组件是“keep-alive”,是一个抽象组件;它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。缓存组件主要用于保留组件状态或避免重新渲染,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 本教程…

    2025年3月11日
    200
  • 工具分享:实现前端埋点的自动化管理

    埋点一直是 H5 项目中的重要一环,埋点数据更是后期改善业务和技术优化的重要基础。【推荐学习:web前端、编程教学】 在日常的工作中,经常会有产品或者业务的同学来问,“这个项目现在有哪些埋点?”,“这个埋点用在哪些地方?”像这样的问题基本上…

    2025年3月11日 编程技术
    200
  • 什么是vue单页面和多页面

    在vue中,单页面全称“SPA单页面应用”,是指只有一个主页面的应用(一个html页面),从而使整个页面更加流畅;单页面应用提供的信息和一些主要内容已经过筛选和控制,可以简单方便地阅读和浏览。多页面全称“MPA多页面应用”,是指包含多个独立…

    2025年3月11日 编程技术
    200
  • vue中的el是指什么简写

    在vue中,el是element的缩写,可称之为挂载点。el的作用是提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标,可以是CSS选择器,也可以是一个HTMLElement实例;在实例挂载之后,元素可以用“vm.$el”访问。 本…

    2025年3月11日
    200
  • vue中mixin和组件的区别是什么

    mixin和组件的区别:组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,单本质上两者还是泾渭分明,相对独立;而mixins在引入组件之后相当于父组件的各种属性方法都被扩充了,会将组件内部的内…

    2025年3月11日
    200

发表回复

登录后才能评论