年度明星项目
介绍
作为前端开发的主力语言,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 文件中补全代码,具体需求如下:
- 在页面初始化时使用
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 |
页面初始化时利用 createProjectItem 函数创建前 15 个项目数据(即 all-data.json 数组中的前 15 项)的列表元素并加载到页面中。当用户点击 加载更多 按钮时,则按顺序再显示 15 个项目数据。直到所有项目数据都展示完毕(共 60 个)。所有项目展示完毕后需要隐藏 加载更多 按钮。项目展示效果如图所示:

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

最终效果可参考文件夹下面的 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";
let allData let pageSize = 15 let count = 1
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()
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' } })
$(".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]); } }); 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)
});
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> `; }
|