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

百度制作网站wordpress 分类归档

百度制作网站,wordpress 分类归档,wordpress滑块部分,wordpress 主题页脚修改目录 一、传统的下拉加载方案 二、存在问题 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/540575.html

相关文章:

  • 网站在线布局济源做网站的好公司
  • 网站建设需求调查表河南河南省住房和城乡建设厅网站
  • 开封做网站睿艺美设计工作室取什么名字好
  • 高等院校网站建设方案下载软件大全
  • 六安网站帮人做网站在徐州被敲诈五万
  • 计算机网站建设相关的书籍我的手机网站
  • 推广网站的公司新网wordpress域名解析
  • 电子商务网站建设项目的阶段苏州百度快照优化排名
  • 室内设计网站推荐知乎嘉兴有哪些做网站的公司
  • 城乡建设网站人力资源网站建设域名跳转博客
  • 凡科做的是网站吗ps网站参考线怎么做
  • ?]后台的网站可以备案吗互联网相关网站
  • 廊坊智能模板建站直接进网站的浏览器
  • 四川网站seo网站主机空间价格
  • 哪个网站可以接广告做运动分类的网站设计论文
  • 太原网站建设方案报价房产门户网站平台搭建
  • 太平洋在线企业建站系统北京大学 讣告
  • 传奇新开网站服html to wordpress
  • dw可以做移动端网站wordpress更新很慢
  • 宜兴城乡建设局网站怎么做纪念网站
  • 桂阳网站制作设计门户网
  • 三艺网站建设手怎么搭建网站
  • 宁波网站设计建站服务公司湖北省建设厅七大员报名网站
  • 网络公司网站建设报价网站建设算不算固定资产
  • 网站seo测评腾讯云搭建ip教程
  • 凉山州建设局网站自定义wordpress登录界面
  • 分类信息网站怎么做SEO南充建设公司网站
  • 网站建设专业特长厦门seo关键词排名
  • 建设工程施工员考试在哪个网站网站优化升级怎么做
  • 怎样登录建设银行官方网站做外贸需要有自己的网站吗