课程列表

介绍

分页是前端页面中必不可少的一项功能,下面让我们一起来完成一个课程列表的分页吧。

准备

开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:

1
2
3
4
5
6
7
8
├── css
│ └── bootstrap.css
├── effect.gif
├── index.html
└── js
├── axios.js
├── carlist.json
└── index.js

其中:

  • css/bootstrap.css 是项目中用到 bootstrap 样式文件。
  • index.html 是主页面。
  • js/carlist.json 是请求需要用到的数据。
  • js/axios.js 是请求需要用到的 axios 文件。
  • js/index.js 是需要补充的 js 文件。
  • effect.gif 是最终效果图。

注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:

1
2
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/9791/10.zip && unzip 10.zip && rm 10.zip

请通过 VS Code 中的 live server 插件启动本项目,让项目运行起来,效果如下:

初始效果

注意:一定要通过 live server 插件启动项目,避免项目无法访问,影响做题。

目标

  1. 完成数据请求(数据来源 js/carlist.json)。在项目目录下已经提供了 axios,考生可自行选择是否使用。
  2. 完成数据分页显示,每页 5 条数据,默认当前页码为第一页(即 pageNum = 1 ),按照顺序第一页显示 1-5 条,第二页显示 6-10 条,依此类推。将每条数据显示到 list-group 元素中。使用已有代码中 list-group,不要修改 list-group 元素的 DOM 结构。动态渲染时,list-group 示例代码可删除。
  3. 当页码为第一页时,上一页为禁用状态(class=disabled),点击无任何变化。
  4. 当页码为最后一页时,下一页为禁用状态(class=disabled),点击无任何变化。
  5. idpagination 元素中正确显示当前页码总页码(即最大页码)。当前页码变量使用 pageNum,总页码变量使用 maxPage。请勿修改当前页码总页码的变量名称,以免造成判题无法通过。

完成后的效果见文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。

规定

  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
  • 请勿修改项目中提供的 idclass、函数名等名称,以免造成无法判题通过。

判分标准

  • 本题完成目标 2 给 10 分,完成目标 3、4、5 各给 5 分。

总通过次数: 1043 | 总提交次数: 1065 | 通过率: 97.9%

难度: 中等 标签: 2022, 省赛, Web 前端, JavaScript

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
let pageNum = 1; // 当前页码,默认页码1
let maxPage; // 最大页数

// TODO:待补充代码
let pageSize = 5
let carList
const listContainer = document.getElementById('list')
const pagination = document.getElementById('pagination')
// 1. 数据请求
getData = async () => {
const response = await axios.get('./js/carlist.json')
console.log(response.data);
carList = response.data
// 2.2 maxPage部分
maxPage = Math.floor(carList.length / pageSize) + 1
await handleData()
await renderData()
}

getData()

// 2. 分页处理数据
// 2.1 showList部分
let showList
handleData = async () => {
showList = carList.slice((pageNum - 1) * pageSize, pageNum * pageSize)
}



// 3. 渲染数据
renderData = async () => {
// 清空之前的listContainer
listContainer.innerHTML = ''

for(let item of showList) {
listContainer.innerHTML += `
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">${item.name}</h5>
<small>${item.price / 100}元</small>
</div>
<p class="mb-1">
${item.description}
</p>
</a>
</div>`
}

pagination.innerText = `共${maxPage}页,当前${pageNum}页`

}




// 点击上一页
let prev = document.getElementById("prev");
prev.onclick = function () {
// TODO:待补充代码
if (pageNum > 1) {
pageNum--
handleData()
renderData()
}
if (pageNum === 1) {
prev.classList.add('disabled')
next.classList.remove('disabled')
} else {
prev.classList.remove('disabled')
next.classList.remove('disabled')
}
};
// 点击下一页
let next = document.getElementById("next");
next.onclick = function () {
// TODO:待补充代码
console.log(pageNum);
console.log(maxPage);
if (pageNum < maxPage) {
pageNum++
handleData()
renderData()
}


if (pageNum === maxPage) {
next.classList.add('disabled')
prev.classList.remove('disabled')
} else {
next.classList.remove('disabled')
prev.classList.remove('disabled')
}
};