今天我们将了解如何从头开始创建分页并使其可访问和可重用。希望对您有帮助,欢迎在文末留言评论!
Github:https://github.com/micaavigliano/accessible-pagination
项目:https://accessible-pagination.vercel.app/
自定义钩子来获取数据
const useFetch = <t>(url: string, currentPage: number = 0, pageSize: number = 20) => { const [data, setData] = useState<t null>(null); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<boolean>(false); useEffect(() => { const fetchData = async() => { setLoading(true); setError(false); try { const response = await fetch(url); if (!response.ok) { throw new Error('network response failed') } const result: T = await response.json() as T; setData(result) } catch (error) { setError(true) } finally { setLoading(false); } }; fetchData() }, [url, currentPage, pageSize]); return { data, loading, error, } }; </boolean></boolean></t></t>
- 我们将生成一个具有通用类型的自定义钩子。这将允许我们指定使用此钩子时期望的数据类型
- 让我们等待3个参数。一个用于 url,我们将在其中获取数据,currentPage 是我们所在的页面,默认情况下它是 0,pageSize 是数字我们每页将包含的项目数,默认情况下为 20(您可以更改此值)。
- 在我们的状态 const [data, setData] = useState
(空);我们将其传递给通用类型 T,因为当我们将它用于不同的数据请求时,我们将期望不同类型的数据。
分页
为了使页面可访问,我们必须考虑以下几点:
- 焦点必须穿过页面的所有交互元素,并有一个可见的指示器
- 为了确保与屏幕阅读器的良好交互,我们必须正确使用区域、属性和状态
- 页面必须分组在标签内,并包含将其标识为页面本身的 aria-label。
- 分页中的每个项目都必须包含 aria-setsize 和 aria-pointset。现在,它们是做什么用的? aria-setsize 用于计算分页列表中的项目总数。屏幕阅读器将按如下方式宣布:
aria-pointset 用于计算该项目在页面上所有项目中的位置。屏幕阅读器将按如下方式宣布:
- 每个项目都必须有一个 aria-label,以便能够识别单击该按钮时我们将转到哪个页面。
- 有按钮可以转到下一个/上一个元素,并且每个按钮都必须有其相应的 aria-label
- 如果我们的分页包含省略号,则必须使用 aria-label 正确标记它
- 每次我们进入新页面时,屏幕阅读器都必须宣布我们所在的页面以及有多少个新项目,如下所示。
为了实现这一点,我们将对其进行如下编码:
const useFetch = <t>(url: string, currentPage: number = 0, pageSize: number = 20) => { const [data, setData] = useState<t null>(null); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<boolean>(false); useEffect(() => { const fetchData = async() => { setLoading(true); setError(false); try { const response = await fetch(url); if (!response.ok) { throw new Error('network response failed') } const result: T = await response.json() as T; setData(result) } catch (error) { setError(true) } finally { setLoading(false); } }; fetchData() }, [url, currentPage, pageSize]); return { data, loading, error, } }; </boolean></boolean></t></t>
当页面停止加载时,我们将使用 currentPage 和我们正在加载的新数组的长度设置一条新消息。
现在是的!让我们看看文件 pagination.tsx
中的代码结构如何该组件需要五个道具
const [statusMessage, setStatusMessage] = useState<string>(""); useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth' }); if (!loading) { setStatusMessage(`Page ${currentPage} loaded. Displaying ${data?.near_earth_objects.length || 0} items.`); } }, [currentPage, loading]); </string>
-
currentPage 将引用当前页面。我们将通过在要使用分页的组件中来处理此问题,如下所示: const [currentPage, setCurrentPage] = useState
(1); - totalPages 是指 API 包含的要显示的项目总数。
- nextPage 此函数将允许我们转到下一页并更新 currentPage 状态,如下所示:
interface PaginationProps { currentPage: number; totalPages: number; nextPage: () => void; prevPage: () => void; goToPage: (page: number) => void; }
- prevPage 此函数将允许我们转到当前页面的上一页并更新 currentPage 状态
const handlePageChange = (newPage: number) => { setCurrentPage(newPage); }; const nextPage = () => { if (currentPage
- goToPage 这个函数需要一个数字参数,它是每个项目必须能够转到所需页面的函数。让我们按如下方式使其工作:
const prevPage = () => { if (currentPage > 1) { handlePageChange(currentPage - 1); } };
为了使我们的分页变得生动,我们还需要一步,创建我们将在列表中迭代的数组!为此,我们必须遵循以下步骤:
- 创建一个函数,在本例中我将其命名为 getPageNumbers
- 为列表中的第一个和最后一个项目创建变量。
- 为左侧的省略号创建一个变量。根据我自己的决定,我的省略号将位于列表的第四个元素之后。
- 为右侧的省略号创建一个变量。根据我自己的决定,我的省略号将放在列表中的三个项目之前。
- 创建一个函数,返回一个数组,其中 5 个项目始终居中,即当前页面、前两个项目和后两个项目。如果需要,我们将排除第一页和最后一页
const pagesAroundCurrent = [currentPage - 2, currentPage - 1, currentPage, currentPage 1, currentPage 2].filter(page => page >firstPage && page
- 对于最后一个变量,我们将创建一个包含所有先前创建的变量的数组。
- 最后,我们将过滤掉空元素并返回数组。
我们将通过该数组来获取页面中的项目列表,如下所示:
const useFetch = <t>(url: string, currentPage: number = 0, pageSize: number = 20) => { const [data, setData] = useState<t null>(null); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<boolean>(false); useEffect(() => { const fetchData = async() => { setLoading(true); setError(false); try { const response = await fetch(url); if (!response.ok) { throw new Error('network response failed') } const result: T = await response.json() as T; setData(result) } catch (error) { setError(true) } finally { setLoading(false); } }; fetchData() }, [url, currentPage, pageSize]); return { data, loading, error, } }; </boolean></boolean></t></t>
以下是如何制作可重用且易于访问的分页!就我个人而言,我学习了如何从头开始创建页面,因为我必须在实时编码中实现它,我希望我的经验对您的职业生涯有所帮助,并且您可以实现甚至改进它!
您好,
云母
以上是可访问的组件:分页的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

记事本++7.3.1
好用且免费的代码编辑器

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境