[ 蓝桥杯Web真题 ]-年度明星项目
目录
引入
介绍
准备
目标
效果
规定
思路
知识补充
解答参考
引入
hello,大家好!我注意到了之前发的一篇蓝桥杯Web应用开发的文章是关注度最高的,可能大部分关注我的小伙伴对蓝桥杯Web应用开发比较感兴趣,或者想要参加,不知道这么准备。但是由于之前发的那一篇只是告诉参赛可以怎样准备,附加的笔记可能也不够详细,而且我发现之前官网免费学习的课程现在需要收费了。┭┮﹏┭┮
因此我打算给各位小伙伴每隔几天比较详细地去发一篇该赛道的真题讲解。每届的真题打算只介绍后面五道,希望能够对大家有帮助。自己介绍的解决思路也不一定是标准的,希望大家能够一起学习进步,有什么更好地思路也可以进行交流学习!
介绍
作为前端开发的主力语言,JavaScript
相关的开源项目是每一个前端开发者都应该多多关注的。我们可以通过这一年新增 star 的数量来判断一个开源项目的流行趋势。
本题请实现一个展示 2022 年 JavaScript
明星开源项目数据的网页。
准备
开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:
├── 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
是页面最终的效果图。
注意:打开环境后发现缺少项目代码,请复制下述命令至命令行进行下载:
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 |
2.页面初始化时利用 createProjectItem
函数创建前 15 个项目数据(即 all-data.json
数组中的前 15 项)的列表元素并加载到页面中。当用户点击 加载更多 按钮时,则按顺序再显示 15 个项目数据。直到所有项目数据都展示完毕(共 60 个)。所有项目展示完毕后需要隐藏 加载更多 按钮。项目展示效果如图所示:
3.当用户点击页面右上方的中英文切换按钮时,根据用户的选择改变项目描述使用的语言(不改变原有项目展示数量)。当用户选择英语模式时的项目展示效果如图所示:
最终效果可参考文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。
效果
规定
请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。先尝试自己做一下:传送门。
思路
其实不要看好像题目要实现的功能或者效果很多,没有啥思路。但是其实按着题目给的思路一步一步地去完成它,并结合一部分提供的代码就能够比较清楚地找到解决思路。
题目主要需要解决的功能点就是使用ajax来进行发送请求,获取数据,然后需要对数据来进行截取,每次15条进行显示。同时需要完成项目描述的中英文切换的功能。
题目给出的代码使用的是jQuery进行编写的,所以在js文件中最好就进行统一,同样地使用jQuery来进行编写。想要完成这道题目你需要先知道如何使用jQuery来发送ajax请求。然后每次展示的数量为15条,可以使用数组中的slice来进行截取。中英文切换可以获取声明的变量,来做判断,若为中文可以将项目的描述赋值为descriptionCN,若为英文则赋值为:descriptionEN。
知识补充
jQuery中的ajax
使用jQuery发送get请求的格式为:$.get(url, [data], [callback], [type])。url:请求的 URL 地址。 data:请求携带的参数。 callback:载入成功时回调函数。 type:设置返回内容格式,xml, html, script, json, text, _default。当请求不需要携带参数时,可以直接传入url以及回调函数。type可以不写,当不写时jQuery会根据响应头中的Content-Type来自动解析返回的数据格式。
$.get('url地址',{name:'N-A'},function(data){
console.log(data);
},json)
使用jQuery发送post请求,格式为:$.post(url,[data],[callback,[type]),url:请求的URL地址,data:请求携带的参数。callback:载入成功时的回调函数。type:设置返回内容格式:xml,html,script,json,text,_default。
$.post('url地址',{name:'N-A'},function(data){
console.log(data);
},json)
除此之外:还可以使用通用的方式:接受的参数有: url,请求携带的参数:data,请求类型:type,响应体结果:dataType以及成功的回调以及失败的回调函数。
$.ajax({
url:'请求地址',
data:{name:'N-A'},
type:'GET',
dataType:'json',
success:function(data){
console.log(data);
},
error:function(){
console.log('出错啦');
}
})
slice方法可以截取原来数组中元素,不会修改原来的数组。语法:array.slice(start,end)。start:表示开始位置,规定从何处开始选取,负数表示从数组尾部开始计算位置。如果省略该参数,默认从索引0开始。end:表示结束位置,规定从何处结束选取,负数表示从尾部开始计算位置。如果省略该参数,默认选取到数组末尾。
let arr=[1,2,3,4,5,6,7];
console.log(arr.slice(2,4));//[3,4]
console.log(arr.slice(2));//[3,4,5,6,7];
console.log(arr.slice(-5,4));//[3,4]
console.log(arr.slice(2,-1));//[3,4,5,6]
console.log(arr.slice(-3));//[5,6,7]
介绍了slice,顺便介绍一些splice方法,该方法用户对数据进行删除以及添加,会改变原本的数组。当传入一个参数时,会从该参数向后全部的数据都删除,返回删除的数据。
let arr=[1,2,3,4,5,6,7];
let arr1=arr.splice(2)
console.log(arr1);//[3,4,5,6,7]
console.log(arr);//[1,2]
当传入两个参数时,第一个参数表示从哪个位置开始删除,第二个参数表示删除多个的元素。返回的是删除的元素。
let arr=[1,2,3,4,5,6,7];
let arr2=arr.splice(1,1)
console.log(arr2);//[2]
console.log(arr);//[1,3,4,5,6,7]
当传入三个参数时,前两个参数,跟上面的一样功能,在此基础上插入第三个参数。返回的同样是删除的元素,
let arr=[1,2,3,4,5,6,7];
let arr3=arr.splice(1,2,66)
console.log(arr3);//[2,3]
console.log(arr);//[1,66,4,5,6,7]
解答参考
首先我们实现项目数据文件和翻译数据文件的请求功能。在请求之前,先声明两个用于存储数据的数组,第一个为items,主要用于存储请求的所有数据。第二个为data,data用于存储在页面展示的数据。
// TODO: 请在此补充代码实现项目数据文件和翻译数据文件的请求功能
$.get('./js/all-data.json',function(res){
items=res;
})
$.get('./js/translation.json',function(res){
translation=res;
})
接着我们编写数据展示的功能,每一次获取需要渲染15条数据,第一次页面加载时就需要显示15条,后续通过点击按钮在实现数据的逐步获取。因此在声明一个index,主要用来记录申请的此时,并赋初始值为1。将获取数据的功能单独地封装成一个函数,当第一次加载时就调用它,然后每次单击按钮时调用它。该方法可以接受一个参数,该参数表示请求的次数,将index传入。
// TODO: 请修改以下代码实现项目数据展示的功能
function getData(num){
data=items.slice(0,num*15);
data.slice(-15).forEach(element => {
element.description = (currLang === "zh-cn") ? element.descriptionCN : element.descriptionEN;
$(".list > ul").append(createProjectItem(element));
});
}
在函数里面使用slice方法来对全部的数据进行截取,首次加载传入index的值为1,它会从0截取到14,一同15条数据。当点击按钮加载更多时,让index++,然后调用getData方法,data的数据就是items的前三十条数据。然后再通过slice方法,传入-15来获取它后面新增的15条数据插入到列表页面中。同时需要判断当前的currLang参数的值,通过三目运算符来为每一个对象再添加一个属性description,该属性的值主要通过currLang的值来决定。
//记录数据需要加载的次数
let index=1;
//请求时调用getData方法
$.get('./js/all-data.json',function(res){
items=res;
getData(index);
})
//点击方法
$(".load-more").click(function(){
index++;
getData(index);
if(data.length>=items.length){
$(this).css('display','none');
}
})
同时判断data的长度是否达到了items数组的长度,若是的话说明数据已经全部都加载完毕了,这时候改变该元素的display属性为none。让其消失。注意:该方法若你使用的是箭头函数的话,$(this)指向的是window。
最后需要实现但点击切换中英文时,项目卡片中的描述可跟着切换。使用到的方式是直接获取它对应的p标签直接改变里面的文字。
// TODO: 请在此补充代码实现项目描述的语言切换
$('ul li p').each(function(index) {
if(currLang == "zh-cn"){
$(this).text(data[index].descriptionCN);
}else{
$(this).text(data[index].descriptionEN);
}
});
完整答案:
// 保存翻译文件数据的变量
let translation = {};
// 记录当前语言
let currLang = "zh-cn";
//保存所有数据
let items=[];
//保存展示的数据
let data=[];
let index=1;
// TODO: 请在此补充代码实现项目数据文件和翻译数据文件的请求功能
$.get('./js/all-data.json',function(res){
items=res;
getData(index);
})
$.get('./js/translation.json',function(res){
translation=res;
})
// TODO-END
// TODO: 请修改以下代码实现项目数据展示的功能
function getData(num){
data=items.slice(0,num*15);
data.slice(-15).forEach(element => {
element.description = (currLang === "zh-cn") ? element.descriptionCN : element.descriptionEN;
$(".list > ul").append(createProjectItem(element));
});
}
$(".load-more").click(function(){
index++;
getData(index);
if(data.length>=items.length){
$(this).css('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: 请在此补充代码实现项目描述的语言切换
$('ul li p').each(function(index) {
if(currLang == "zh-cn"){
$(this).text(data[index].descriptionCN);
}else{
$(this).text(data[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>
`;
}
好啦,本文就到这里了,期待下次再见!