在网络上,分页是将大块内容分解成更小的块的一种方法。在本文中,我们将介绍一种使用 HTML、CSS 和普通 JavaScript 将内容划分为一系列“页面”的简单方法。
虽然分页可以使用 React 和 Angular 等框架来实现,但本文的目的是提供一个简单、分步的分页设置指南,以便我们能够理解所涉及的基本概念。
创建我们的基本网页
在实现我们的分页系统之前,让我们创建一个 HTML 结构来存储我们想要显示的内容。这可以是任何类型的内容,但在本教程中,我们将使用一个 5 列 15 行的表来存储不同年级学生的姓名。这是我们的 HTML 片段:
<article class="content"> <table> <thead> <tr> <th>Grade 1</th> <th>Grade 2</th> <th>Grade 3</th> <th>Grade 4</th> <th>Grade 5</th> </tr> </thead> <tbody> <tr> <td>Faith Andrew</td> <td>Angela Christopher`</td> <td>David Elias</td> <td>Samuel Thomas</td> <td>Richard Elias</td> </tr> ⋮ </tbody> </table> </article>
我们已将表格包装在容器元素 ( <article class="content">
) 中。虽然我们并不严格需要容器元素,但拥有它很方便,特别是当我们的页面上还有其他元素时。(它为我们将添加的分页按钮提供了有用的上下文。)
您可以在CodePen上查看我们完整的 HTML 代码以及一些样式。
使用 JavaScript 实现分页功能
HTML 和 CSS 就位后,下一步就是实现分页。我们首先使用 JavaScript 将表格划分为不同的“页面”,并添加用于导航这些页面的按钮功能。
创建一个将表格分为页面的函数
这是我们将表分成单独部分的代码:
document.addEventListener('DOMContentLoaded', function () { const content = document.querySelector('.content'); const itemsPerPage = 5; let currentPage = 0; const items = Array.from(content.getElementsByTagName('tr')).slice(1);
第一行创建一个事件侦听器,确保 JavaScript 代码在 HTML 内容完全加载和解析后运行。这是为了防止在内容在 DOM 中可用之前对元素进行任何操作或交互。
使用document.querySelector('.content')
,我们选择<article class="content">
包装器并将其初始化为变量。
使用const itemsPerPage = 5;
,我们可以设置每页上显示的行数。
使用let currentPage = 0;
,我们创建一个变量来跟踪当前页码。它从 0 开始,代表第一页。(JavaScript 中的第一个索引是 0,因此它从 0 开始计数,而不是从 1 开始。)
最后一行使用该getElementsByTagName
方法选择<tr>
表中带有标签的所有元素。我们创建一个包含items
所有子元素的数组 ( ),并使用slice(1)
排除第一行(标题)并创建一个包含其余行的数组。
这意味着当我们切换页面时标题将保持不变。
开发 showPage() 功能
接下来,我们来编写显示页面的代码:
function showPage(page) { const startIndex = page * itemsPerPage; const endIndex = startIndex + itemsPerPage; items.forEach((item, index) => { item.classList.toggle('hidden', index < startIndex || index >= endIndex); }); updateActiveButtonStates(); }
我们首先创建一个showPage()
接受page
参数的函数。该函数负责在调用时显示连接到该特定页面的项目。
接下来,我们startIndex
通过将 page 参数乘以 来计算 ,它是当前页面上应显示的第一个项目itemsPerPage
。我们还计算endIndex
紧随当前页面上应显示的最后一项之后的 。
通过这样做,我们创建了一系列要显示的项目。例如,假设我们有十个项目,我们希望每页显示五个项目。如果我们位于第一页 (page = 0),startIndex
则为 0,并且endIndex
为 0 + 5 = 5。此范围 ([0, 5]) 包括前五个项目。在下一页 (page = 1) 上,startIndex 将为 5,并且endIndex
将为 5 + 5 = 10。此范围 ([5, 10]) 包括其余项目。
使用items.forEach()
,我们创建一个循环,迭代每一行并检查其索引是否落在当前页面上显示的项目范围内 - 也就是说,它是否位于 之前或之后/startIndex
等于endIndex
。如果索引在范围内,toggle
关键字会将hidden
类(我们将在 CSS 代码中定义)应用于该项目,从而有效地隐藏它。如果索引不满足任一条件,则hidden
删除该类,使该项目可见。
我们的hidden
类将项目移出屏幕,将它们隐藏起来,但仍然允许使用屏幕阅读器的人访问它们:
.hidden { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }
添加按钮
现在让我们看看如何添加导航按钮。在下面的代码中,我们将根据表格的内容创建并添加按钮功能:
function createPageButtons() { const totalPages = Math.ceil(items.length / itemsPerPage); const paginationContainer = document.createElement('div'); const paginationDiv = document.body.appendChild(paginationContainer); paginationContainer.classList.add('pagination');
首先,我们创建一个createPageButtons()
函数来存储创建按钮的逻辑。然后我们计算显示表格所需的总页数。我们通过将项目总数除以每页所需的项目数来实现此目的。使用该函数对结果进行舍入Math.ceil()
。这确保了表项的所有行都被可用页面覆盖。
接下来,我们创建一个 div 来包含动态生成的页面按钮 ( document.createElement('div')
)。然后我们<div>
使用 将该元素附加到 HTML 结构的主体中document.body.appendChild(paginationDiv)
。(我们实际上并没有告诉它在 HTML 结构中的位置,是的。我们很快就会这样做。)最后,我们向该按钮容器添加一个类,pagination
以便我们可以使用样式来定位它。
下一步是为每个页面创建按钮,使用循环迭代每个可能的页面索引:
for (let i = 0; i < totalPages; i++) { const pageButton = document.createElement('button'); pageButton.textContent = i + 1; pageButton.addEventListener('click', () => { currentPage = i; showPage(currentPage); updateActiveButtonStates(); });
循环for
范围从 0(即第一页)到总页数减 1。
在每次页面迭代中,使用该方法创建一个新的单独页面按钮document.createElement()
,每次循环时将页码增加 1。
接下来,我们创建一个单击事件侦听器并将其附加到页面按钮。单击按钮时,将执行事件侦听器的回调函数。
下面是回调函数的解释:
该
currentPage
变量将更新为 的当前值i
,该值对应于单击的页面的索引。showPage()
使用更新后的值调用该函数currentPage
,从而显示单击页面的内容。
为了完成我们的按钮创建代码,我们以此结束:
content.appendChild(paginationContainer); paginationDiv.appendChild(pageButton);
我们将按钮容器附加到包装器的末尾.content
,然后将按钮放置在按钮容器内。
突出显示活动按钮
为了使我们的按钮更加用户友好,我们将为当前“活动”按钮添加独特的样式。让我
function updateActiveButtonStates() { const pageButtons = document.querySelectorAll('.pagination button'); pageButtons.forEach((button, index) => { if (index === currentPage) { button.classList.add('active'); } else { button.classList.remove('active'); } }); }
首先,我们使用 检索所有分页按钮document.querySelectorAll
并将它们分配给pageButtons
变量。
然后,该updateActiveButtonStates()
函数使用循环逐一遍历每个按钮forEach
,并将其索引与变量的值进行比较currentPage
。
接下来,如果按钮的索引与当前页面匹配,我们使用条件if
语句来分配类的样式。active
如果按钮的索引与当前页面不匹配,active
则删除该类。这可确保其他按钮不会保留该类active
。
为了实现此功能,updateActiveButtonStates()
每当页面更改或显示时我们都会调用该函数。
调用脚本
我们的分页脚本以以下两行结束:
createPageButtons(); showPage(currentPage);
createPageButtons()
我们在函数之前调用函数showPage()
。这可确保在页面加载后创建按钮。
我们的脚本现在计算每个页面要显示的适当项目范围,侦听按钮单击并更新页面显示。
使我们的代码适应其他场景
我们创建的脚本可以很方便地将表分成一系列页面。但是如果我们的内容不是表格怎么办?让我们尝试使用其他类型的内容来尝试我们的脚本,而不是表格内容。
部分元素的分页
让我们<section>
在容器中放置一些元素,而不是表元素,然后看看如何调整我们的脚本。这是我们的基本 HTML:
<article class="content"> <section></section> <section></section> <section></section> <section></section> <section></section> </article>
我们只需要对脚本进行三个非常简单的更改:
document.addEventListener('DOMContentLoaded', function () { const content = document.querySelector('.content'); const itemsPerPage = 1; let currentPage = 0; const items = Array.from(content.getElementsByTagName('section')).slice(0);
变化是:
设置
itemsPerPage
为 1,以便每页仅显示一个部分将目标标签名称更改为
section
,因为我们现在循环遍历<section>
元素而不是<tr>
元素设置
slice()
为 0,这将选择限制为第一个部分元素(索引为 0)
下面的 CodePen 演示展示了这一点:https://codepen.io/SitePoint/pen/XWoJKMX。
无序列表的分页
我们可以轻松地调整上面的演示以处理项目列表。在下面的示例中,我们将包装元素从 an 更改<article>
为 a <ul>
,并将<section>
elements 更改为<li>
elements:
<ul class="content"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul>
在 JavaScript 中,我们只需进行两处更改:
getElementsByTagName('section')
变成getElementsByTagName('li')
让我们设置
const itemsPerPage
为2
每页显示两个列表项
在对无序列表进行一些小的 CSS 更改后,我们最终得到以下结果。演示地址:https://codepen.io/SitePoint/pen/KKbwMyO
结论
在本教程中,我们学习了如何使用 HTML、CSS 和 JavaScript 实现分页。对于那些没有启用 JavaScript 的人(无论出于何种原因),完整的内容仍然可用 - 只是没有分页。通过使用语义<button>
元素,页面仍然可以通过键盘访问。我们还通过将非活动内容移出屏幕而不是使用 来隐藏非活动内容display: none
,以便屏幕阅读器仍然可以访问它。
我们可以进一步添加描述性 ARIA 标签和属性,以向屏幕阅读器传达分页按钮等元素的用途和作用。
我希望这个演示能让您思考简单的分页功能,而无需使用框架。
网友评论文明上网理性发言 已有0人参与
发表评论: