年度明星项目

介绍

作为前端开发的主力语言,JavaScript 相关的开源项目是每一个前端开发者都应该多多关注的。我们可以通过这一年新增 star 的数量来判断一个开源项目的流行趋势。

本题请实现一个展示 2022 年 JavaScript 明星开源项目数据的网页。

准备

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

1
2
3
4
5
6
7
8
9
10
├── css
│ └── style.css
├── effect.gif
├── images
├── index.html
└── js
├── all-data.json
├── index.js
├── jquery-3.6.0.min.js
└── translation.json

其中:

  • css/style.css 是样式文件。
  • index.html 是主页面。
  • images 是图片文件夹。
  • js/all-data.json 是项目数据文件。
  • js/index.js 是需要补充代码的 js 文件。
  • js/jquery-3.6.0.min.js 是 jQuery 库文件。
  • js/translation.json 是页面所用到的翻译数据。
  • effect.gif 是页面最终的效果图。

注意:打开环境后发现缺少项目代码,请复制下述命令至命令行进行下载:

1
2
3
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/18213/2022-JavaScript.zip
unzip 2022-JavaScript.zip && rm 2022-JavaScript.zip

在浏览器中预览 index.html 页面效果如下:

图片描述

目标

请在 js/index.js 文件中补全代码,具体需求如下:

  1. 在页面初始化时使用 AJAX 请求地址为 ./js/all-data.json 以及 ./js/translation.json 文件中的数据(必须使用给定的路径请求,否则可能会请求不到数据),并将后者中的数据保存至 translation 变量中。其中 all-data.json 文件中以数组的形式存储了明星项目的数据,translation.json 文件中包含了网站中英文转换所需的数据。

all-data.json 数据参数说明:

参数 说明 类型
name 项目名称 string
icon 项目 icon 路径 string
stars 项目新增 star 数量 number
descriptionCN 项目中文描述 string
descriptionEN 项目英文描述 string
tags 项目标签列表 array
  1. 页面初始化时利用 createProjectItem 函数创建前 15 个项目数据(即 all-data.json 数组中的前 15 项)的列表元素并加载到页面中。当用户点击 加载更多 按钮时,则按顺序再显示 15 个项目数据。直到所有项目数据都展示完毕(共 60 个)。所有项目展示完毕后需要隐藏 加载更多 按钮。项目展示效果如图所示:

    项目展示效果

  2. 当用户点击页面右上方的中英文切换按钮时,根据用户的选择改变项目描述使用的语言(不改变原有项目展示数量)。当用户选择英语模式时的项目展示效果如图所示:

    中英文切换效果

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

规定

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

判分标准

  • 完成目标 1,得 5 分。
  • 完成目标 2,得 10 分。
  • 完成目标 3,得 5 分。

总通过次数: 384 | 总提交次数: 566 | 通过率: 67.8%

难度: 中等 标签: 蓝桥杯, 2023, 省赛, Web 前端, JavaScript, JS 函数封装, 异步

题解

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
97
98
99
100
101
102
103
104
105
106
107
108
// 保存翻译文件数据的变量
let translation = {};
// 记录当前语言
let currLang = "zh-cn";

// data
let allData
let pageSize = 15
let count = 1

// TODO: 请在此补充代码实现项目数据文件和翻译数据文件的请求功能
const fetchData1 = async () => {
const response = await fetch('./js/all-data.json', {method: 'get'})
const data = await response.json()
return data
}

const fetchData2 = async () => {
const response = await fetch('./js/translation.json', {method: 'get'})
const data = await response.json()
return data
}

const fn = async () => {
allData = await fetchData1()
translation = await fetchData2()
console.log(allData);
console.log(translation);
renderData()
}

fn()

// TODO-END

// TODO: 请修改以下代码实现项目数据展示的功能
const renderData = async () => {
console.log(allData);
for(let item of allData.slice(pageSize * (count - 1),pageSize * count)) {
currLang === 'zh-cn' ? item.description = item.descriptionCN : item.description = item.descriptionEN
$(".list > ul").append(createProjectItem(item));
}
}

const loadMoreBtn = document.getElementsByClassName('load-more')[0]
loadMoreBtn.addEventListener('click', () => {
count++
renderData()
if (count === 4) {
loadMoreBtn.style.display = 'none'
}
})

// TODO-END

// 用户点击切换语言的回调
$(".lang").click(() => {
// 切换页面文字的中英文
if (currLang === "en") {
$(".lang").text("English");
currLang = "zh-cn";
} else {
$(".lang").text("中文");
currLang = "en";
}
$("body")
.find("*")
.each(function () {
const text = $(this).text().trim();
if (translation[text]) {
$(this).text(translation[text]);
}
});
// TODO: 请在此补充代码实现项目描述的语言切换
const pArr = document.querySelectorAll('.desc p')
currLang === 'zh-cn' ?
pArr.forEach((item,index) => item.innerText = allData[index].descriptionCN)
:
pArr.forEach((item,index) => item.innerText = allData[index].descriptionEN)

});

// 生成列表DOM元素的函数,将该元素的返回值append至列表中即可生成一行项目数据
/**
* @param {string} name - 项目名称
* @param {string} description - 项目描述
* @param {string[]} tags - 项目标签
* @param {number} stars - 项目star数量
* @param {string} icon - 项目icon路径
*/
function createProjectItem({ name, description, tags, stars, icon }) {
return `
<li class="item">
<img src="images/${icon}" alt="">
<div class="desc">
<h3>${name}</h3>
<p>${description}</p>
<ul class="labels">
${tags.map((tag) => `<li>${tag}</li>`).join("")}
</ul>
</div>
<div class="stars">
+${stars} 🌟
</div>
</li>
`;
}