当前位置: 首页 > wzjs >正文

武汉设计网站的公司陕西疫情最新消息

武汉设计网站的公司,陕西疫情最新消息,我要自学网网页制作视频教程,国内时事新闻2023最新目录 一、传统的下拉加载方案 二、存在问题 1.性能较差 2.不够精确 三、IntersectionObserve版本下拉加载 1、callback 2、options 四、IntersectionObserver实例 1、Intersection的优势 2、实现思路 3、代码实现 在进行前端开发的过程中,常常会碰到下拉…

目录

一、传统的下拉加载方案

二、存在问题

1.性能较差

2.不够精确

三、IntersectionObserve版本下拉加载

1、callback

2、options

四、IntersectionObserver实例

1、Intersection的优势

2、实现思路

3、代码实现


在进行前端开发的过程中,常常会碰到下拉加载列表数据的需求。本文将介绍如何利用Intersection API实现一个简单的下拉加载数据的demo。

一、传统的下拉加载方案

传统的下拉加载方案大多数都是通过监听scroll事件,然后获取目标元素坐标以及相关数据,再进行对应的实现。例如下面就是一个依赖数据列表容器的scrollHeightscrollTopheight实现的下拉加载的demo。

function App() {// 用于记录当前是否正在请求中const loadingRef = useRef<boolean>(false);// 列表容器const containerRef = useRef<HTMLDivElement>(null);const [dataList, setDataList] = useState([]);useEffect(() => {fetchData();}, []);useEffect(() => {const { height } = containerRef.current.getBoundingClientRect();const scrollHeight = containerRef.current.scrollHeight;const onScroll = () => {console.log('scrollHeight:', scrollHeight, 'scrollTop:', containerRef.current.scrollTop, 'height:', height);if (scrollHeight - containerRef.current.scrollTop - 1 <= height) {// 当容器已经拉到最底部时,发起请求fetchData();}};containerRef.current.addEventListener('scroll', onScroll);return () => {containerRef.current.removeEventListener('scroll', onScroll);};}, []);const fetchData = () => {// 模拟数据请求// 如果当前正在请求中,直接返回if (loadingRef.current) return;// 标记当前正在请求中loadingRef.current = true;setTimeout(() => {setDataList(_dataList => {const dataList = [..._dataList];for (let i = 0; i < 20; i++) {dataList.push(Math.random());}return dataList;});loadingRef.current = false;}, 500);};return (<div ref={containerRef} className="list-container">{dataList.map(item => (<p className="list-item" key={item}>{item}</p>))}<div className="loading">loading...</div></div>);
}

二、存在问题

1.性能较差

我们知道,scroll事件的发生是十分密集的,在监听scroll事件的回调函数中,我们都要重新获取列表容器的scrollTop,这会导致“重排”的发生。此时需要我们额外去做一些防抖或是节流的工具,防止造成性能问题。

// 节流
throttle(onScroll, 500);

2.不够精确

scrollTop的小数问题 眼尖的同学可能已经看到的,我们在判断容器是否已经滚动到底部是,还做了一个-1的操作。

if (scrollHeight - containerRef.current.scrollTop - 1 <= height) {// 当容器已经拉到最底部时,发起请求fetchData();
}

这是因为在使用显示比例缩放的系统上,scrollTop可能会提供一个小数。如下图所示,在容器滚动到底部时,scrollHeight(1542) - scrollTop(1141.5999755859375) 与容器的高度height(400)并不相等。

所以我们需要做出相应的兼容处理。

三、IntersectionObserve版本下拉加载

IntersectionObserver 提供了一种异步观察目标元素在其祖先元素或顶级文档视窗(viewport)中是否可视的方法。

IntersectionObserver的用法十分简单,我们只需要定义好DOM元素的可视状态发生变化后需要做些什么,以及需要观察哪些元素的可视状态就好了。

接下来我们详细的看看intersectionObserver这个API。

const intersectionObserver = new IntersectionObserver(callback, options?) ;

 IntersectionObserver构造函数会接收两个参数。

1、callback

callback为被观察元素的可视状态发生变更后的回调函数,此回调函数接受两个参数:

function callback(entries, observer?) => {//...
}

entries:一个IntersectionObserverEntry对象的数组。IntersectionObserverEntry对象用于描述被观察对象的可视状态的变化,拥有以下的属性:

  • entry.boundingClientRect:被观察元素的边界信息,相当于被观察元素调用getBoundingClientRect()的结果。
  • entry.intersectionRatio:被观察元素与容器元素相交矩形面积与被观察元素总面积的比例。
  • entry.intersectionRect:相交矩形的边界信息。
  • entry.isIntersecting:一个布尔值,表示被观察元素是否可视,如果是true,则表示元可视,反之则表示不可视。
  • entry.rootBounds:容器元素的边界信息,相当于容器元素调用getBoundingClientRect()的结果。
  • entry.target:被观察的元素的引用。
  • entry.time:当前时间戳。

observer:当前IntersectionObserver实例的引用。

2、options

options为一个可选参数,可传入以下属性:

  • root:指定容器元素,默认为浏览器窗体元素。容器元素必须是目标元素的祖先节点。
  • rootMargin:用于扩展或缩小rootBounds的大小,用法与CSS中margin一致,默认值为默认值是"0px 0px 0px 0px"。
  • threshold:number或number数组,用于指定callback回调函数执行的阈值,如传入[0, 0.2, 0.6, 0.8, 1]时,intersectionRatio每增加或减少0.2时都会触发回调函数的执行。默认值为0。需要注意的时,由于回调函数时异步触发的,在回调函数执行时intersectionRatio可能已经和指定的阈值不一致了。

四、IntersectionObserver实例

IntersectionObserver构造函数会把options中的属性挂载到IntersectionObserver实例上,并赋予IntersectionObserver实例四个方法:

  • IntersectionObserver.disconnect():停止监听工作。
  • IntersectionObserver.observe(targetElem):开始监听某个元素可视状态的变化。
  • IntersectionObserver.takeRecords():返回所有观察目标的IntersectionObserverEntry对象数组。
  • IntersectionObserver.unobserve(targetElem):停止监听某个目标元素。

1、Intersection的优势

intersectionObserver构造函数中传入的回调函数只会在观察的元素的可视状态发生变化后才会执行,很好的解决传统判断可视的方案的性能瓶颈。

2、实现思路

我们在实现下拉加载功能时,当数据列表还没有加载完时,我们往往会在数据列表的最后放置一个loading组件,表示当数据列表还有更加数据,并且正在加载中。我们可以利用这个loading组件的可视状态以及Intersection API实现Intersection版本的下拉加载。

3、代码实现

实现一个DemoList.tsx

import { useEffect, useRef, useState } from 'react';const DemoList = () => {// 用于记录当前是否正在请求中const loadingRef = useRef<boolean>(false);// loading divconst loadingDivRef = useRef<HTMLDivElement | null>(null);const observerRef = useRef<IntersectionObserver | null>(null);const [dataList, setDataList] = useState<number[]>([]);const fetchData = () => {// 模拟数据请求// 如果当前正在请求中,直接返回if (loadingRef.current) return;// 标记当前正在请求中loadingRef.current = true;setTimeout(() => {setDataList((_dataList) => {const dataList = [..._dataList];for (let i = 0; i < 100; i++) {// 这里面要注意的是把最新的请求的数据合并的时候要放在最后面,也就是说从数据的最后面添加。否则,就会出现连续请求的状况。原因在于如果把最新的请求对的数据放最前面的话,新增的元素是从上面渲染,就会导致下面的加载元素一直处于可见的状态,从而导致连续触发的状况dataList.push(Math.random());}return dataList;});loadingRef.current = false;}, 500);};useEffect(() => {fetchData();}, []);useEffect(() => {const target = loadingDivRef.current;if (!target) return;observerRef.current = new IntersectionObserver(function (entries) {if (entries[0].intersectionRatio > 0) {// intersectionRatio大于0,代表监听的元素由不可见变成可见,进行数据请求fetchData();}});// 监听Loading div的可见性if (loadingDivRef.current) observerRef.current.observe(loadingDivRef.current);return () => {if (observerRef.current) {if (target) observerRef.current.unobserve(target);observerRef.current.disconnect();observerRef.current = null;}};}, []);return (<div className="list-container">{dataList.map((item, index) => (<p className="list-item" key={item}>{index}——{item}</p>))}<div ref={loadingDivRef} className="loading">loading...</div></div>);
};export default DemoList;

http://www.dtcms.com/wzjs/499106.html

相关文章:

  • 婚恋网站模板草根seo博客
  • 郑州网站建设咨询链接提交
  • 做优化网站哪个公司好无代码免费web开发平台
  • 上海网站建设 zl产品线下推广方式都有哪些
  • 全网营销推广 好做吗惠州市seo广告优化营销工具
  • 安网站建设公司广东疫情最新数据
  • 网站建设的方案抚顺优化seo
  • 可以和朋友合资做网站吗最近的国内新闻
  • 网站首页代码长沙百度贴吧
  • cms建站系统安装优化清理大师
  • wordpress站点标题添加下载百度app到桌面
  • 会员卡管理系统免费版太原seo网站优化
  • 建筑类专业做教育的网站抖音seo供应商
  • 国内十大网站建设品牌seo引擎优化教程
  • 室内设计和网站建设哪个前景好天津百度搜索排名优化
  • 郑州正规公司网站建设服务网络营销策略的概念
  • 有哪些做网站的网站如何做网站推广及优化
  • 下载的网站模板怎么编辑企业网络组网设计
  • vs做的网站案例网站推广排名教程
  • 武威做网站的百度网盘电脑版登录入口
  • 网站开发有哪些模块企业网络营销策划方案
  • 上传视频网站源码宣传推广的形式有哪些
  • 自己想做网站怎么做网站推广是什么
  • 怎么找做网站的客户企业营销网站建设系统
  • 最强商城系统深圳seo专家
  • 做5g网站seo网站优化服务
  • 郑州做网站 汉狮网络关键词优化分析工具
  • 什么是网站app建设江西省水文监测中心
  • 找印度人做网站湖南百度seo排名点击软件
  • 如何使网站能被百度搜到搜索点击软件