前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【JavaScript——页面加载】年度明星项目(蓝桥杯真题-5138)【合集】

【JavaScript——页面加载】年度明星项目(蓝桥杯真题-5138)【合集】

作者头像
Rossy Yan
发布2025-03-27 09:10:40
发布2025-03-27 09:10:40
4400
代码可运行
举报
运行总次数:0
代码可运行

背景介绍

作为前端开发的主力语言,JavaScript 相关的开源项目是每一个前端开发者都应该多多关注的。我们可以通过这一年新增 star 的数量来判断一个开源项目的流行趋势。 本题请实现一个展示 2022 年 JavaScript 明星开源项目数据的网页。

准备步骤

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

代码语言:javascript
代码运行次数:0
运行
复制
├── 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 是页面最终的效果图。

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

代码语言:javascript
代码运行次数:0
运行
复制
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项目名称stringicon项目 icon 路径stringstars项目新增 star 数量numberdescriptionCN项目中文描述stringdescriptionEN项目英文描述stringtags项目标签列表array 2. 页面初始化时利用 createProjectItem 函数创建前 15 个项目数据(即 all-data.json 数组中的前 15 项)的列表元素并加载到页面中。当用户点击 加载更多 按钮时,则按顺序再显示 15 个项目数据。直到所有项目数据都展示完毕(共 60 个)。所有项目展示完毕后需要隐藏 加载更多 按钮。项目展示效果如图所示:

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

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


要求规定

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

判分标准

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

通关代码✔️

代码语言:javascript
代码运行次数:0
运行
复制
let data = []
// 保存翻译文件数据的变量
let translation = {};
// 记录当前语言
let currLang = "zh-cn";
var page = 0
// TODO: 请在此补充代码实现项目数据文件和翻译数据文件的请求功能
window.onload= async()=>{
  const res1 = await fetch("./js/all-data.json ")
  data = await res1.json()
  const res2 = await fetch("./js/translation.json")
  translation = await res2.json()
  data.slice(0,15).forEach((item)=>{
    $(".list > ul").append(createProjectItem({...item,description:(currLang=="zh-cn"?item.descriptionCN:item.descriptionEN)}));
  })
  document.querySelector(".load-more").addEventListener("click",function(){
    data.slice((page+1)*15,(page+2)*15).forEach((item)=>{
      $(".list > ul").append(createProjectItem({...item,description:(currLang=="zh-cn"?item.descriptionCN:item.descriptionEN)}));
    });
    page++
    if(page == Math.ceil(data.length/15) - 1){
      this.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]);
      }
    });
  // TODO: 请在此补充代码实现项目描述的语言切换
  document.querySelectorAll("body > div.container > div.list > ul > li > div.desc > p").forEach((item)=>{
    item.textContent=
    currLang == "zh-cn"
    ?data.find(i=>i.descriptionEN==item.textContent).descriptionCN
    :data.find(i=>i.descriptionCN==item.textContent).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>
  `;
}

代码解析📑

一、HTML 部分

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>年度明星项目</title>
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
    />
    <script
      src="js/jquery-3.6.0.min.js"
      type="text/javascript"
      charset="utf-8"
    ></script>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
  </head>

  <body>
    <div class="container">
      <div class="head">
        <header>
          <h1>JavaScript明星项目</h1>
          <div class="lang">English</div>
        </header>
      </div>
      <div class="banner">2022 年 JavaScript 明星项目</div>
      <div class="intro">
        <p>欢迎来到2022 JavaScript明星项目网站!</p>
        <p>
          在这里,我们将对过去 12 个月里 JavaScript 生态中的趋势性项目做一个总结。今年的冠军是一个带有微笑标志的美味面包,用微笑开启新的一年是不错的开始!
        </p>
        <hr />
        <p class="small">
          下面的列表中展示了各个项目在 GitHub 上于过去 12 个月新增的 star 数量。分析的数据来源为 Best of JS 网站 ,一个 web 领域优秀项目的精选网站。
        </p>
      </div>
      <div class="list">
        <h2>最受欢迎项目</h2>
        <ul></ul>
        <div class="load-more">加载更多</div>
      </div>
    </div>
    <script src="js/index.js"></script>
  </body>
</html>
  • <!DOCTYPE html> 声明文档类型为 HTML5。
  • <html> 是整个 HTML 文档的根元素。
  • <head> 部分:
    • <meta charset="UTF-8"> 设置文档的字符编码为 UTF-8。
    • <title> 设置页面标题为 “年度明星项目”。
    • <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"> 用于设置页面在移动端的显示效果,使其适应设备宽度,禁止用户缩放。
    • 引入了 jQuery 库文件 js/jquery-3.6.0.min.js,以便在 JavaScript 中使用 jQuery 提供的功能。
    • 引入了外部 CSS 样式表 css/style.css,用于定义页面的样式。
  • <body> 部分:
    • <div class="container"> 是页面的主要容器。
      • <div class="head"> 包含页面的头部信息,其中 <header> 内有页面标题 <h1>JavaScript明星项目</h1> 和语言切换按钮 <div class="lang">English</div>
      • <div class="banner"> 显示 “2022 年 JavaScript 明星项目” 的横幅信息。
      • <div class="intro"> 包含页面的介绍文本,描述了网站的功能和数据来源等信息。
      • <div class="list"> 包含项目列表部分,<h2>最受欢迎项目</h2> 是列表标题,<ul></ul> 用于显示项目列表项,<div class="load-more">加载更多</div> 是加载更多数据的按钮。
    • 最后引入了自定义的 JavaScript 脚本文件 js/index.js,用于实现页面的交互功能。

二、CSS 部分

代码语言:javascript
代码运行次数:0
运行
复制
:root {
  --orange: #cc4700;
}

body {
  margin: 0;
  padding: 0;
  background-color: rgb(239, 239, 236);
  color: #541600;
}

.head {
  display: flex;
  width: 100vw;
  justify-content: center;
  background-color: white;
}

header {
  color: #cc4700;
  display: flex;
  width: 100%;
  max-width: 1200px;
  justify-content: space-between;
  padding: 0 1rem;
  align-items: center;
  box-sizing: border-box;
}

header h1 {
  margin: 1rem;
}

.lang {
  font-family: "Times New Roman", Times, serif;
  cursor: pointer;
  font-size: 110%;
}

.lang:hover {
  color: rgba(204, 71, 0, 0.8);
}

.banner {
  background-color: #e65100;
  color: white;
  font-size: 300%;
  text-align: center;
  font-family: Space Mono, monospace;
  height: 300px;
  display: grid;
  align-items: center;
  margin-bottom: 2rem;
}

.intro {
  padding: 2rem;
  border: 1px solid #788080;
  max-width: 650px;
  margin: auto;
  margin-bottom: 2rem;
  font-size: 20px;
}

.small {
  font-size: 16px;
}

.list {
  max-width: 1200px;
  margin: auto;
}

.list h2 {
  font-size: 1.3rem;
  border: 1px solid #788080;
  margin-bottom: 40px;
  text-align: center;
  padding: 2rem;
}

.list ul {
  list-style: none;
  width: 650px;
  margin: auto;
}

.list .item {
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  gap: 1rem;
  border-top: #bbb dashed 1px;
}

.list .item:last-child {
  border-bottom: #bbb dashed 1px;
}

.list img {
  width: 60px;
}

.list .desc {
  font-family: "Times New Roman", Times, serif;
  width: 400px;
  padding: 1rem 0;
}

.list .desc h3 {
  color: #e65100;
  font-weight: 400;
  font-family: "Courier New", Courier, monospace;
  margin: 0;
}

.list .desc p {
  margin: 0.5rem 0;
}

.list .desc .labels {
  display: flex;
  gap: 1rem;
  padding: 0;
}

.list .desc .labels li {
  padding: 0.5rem;
  color: rgba(84, 22, 0, 0.6);
  border: 1px solid rgba(84, 22, 0, 0.2);
  border-radius: 5px;
  font-family: sans-serif;
  font-size: 0.8rem;
}

.list .stars {
  font-family: monospace;
  font-size: 1.1rem;
}

.load-more {
  font-size: 1.3rem;
  border: 1px solid #788080;
  margin: 40px 0;
  text-align: center;
  padding: 2rem;
  color: #e65100;
  cursor: pointer;
}

.load-more:hover {
  background-color: white;
}
  • :root 选择器定义了一个全局变量 --orange,值为 #cc4700,用于统一管理颜色。
  • body 选择器设置页面的边距、内边距、背景颜色和文本颜色。
  • .head 类设置头部容器的显示方式为 flex 布局,宽度为视口宽度,背景颜色为白色,并居中内容。
  • header 类设置头部内容的颜色、显示方式为 flex 布局,最大宽度为 1200px,水平方向上两端对齐,垂直方向上居中内容。
  • .lang 类设置语言切换按钮的字体、鼠标样式和字体大小,:hover 伪类设置鼠标悬停时的颜色变化。
  • .banner 类设置横幅的背景颜色、文本颜色、字体大小、文本对齐方式、字体类型、高度和显示方式为 grid 布局,并设置底部外边距。
  • .intro 类设置介绍部分的内边距、边框、最大宽度、居中显示和字体大小。
  • .small 类设置特定段落的字体大小。
  • .list 类设置项目列表容器的最大宽度并居中显示。
  • .list h2 类设置列表标题的字体大小、边框、底部外边距、文本对齐方式和内边距。
  • .list ul 类设置列表的样式,去除默认的列表符号,并设置宽度和居中显示。
  • .list .item 类设置项目列表项的显示方式为 flex 布局,垂直方向上居中内容,水平方向上均匀分布元素,设置元素间的间距和顶部边框。
  • .list .item:last-child 类设置最后一个项目列表项的底部边框。
  • .list img 类设置项目图标图片的宽度。
  • .list .desc 类设置项目描述部分的字体、宽度和内边距。
  • .list .desc h3 类设置项目描述标题的颜色、字体权重、字体类型和边距。
  • .list .desc p 类设置项目描述段落的底部外边距。
  • .list .desc .labels 类设置项目标签列表的显示方式为 flex 布局和元素间的间距。
  • .list .desc .labels li 类设置项目标签的内边距、颜色、边框、边框半径、字体和字体大小。
  • .list .stars 类设置项目星星数量的字体和字体大小。
  • .load-more 类设置加载更多按钮的字体大小、边框、外边距、文本对齐方式、内边距、颜色和鼠标样式,:hover 伪类设置鼠标悬停时的背景颜色变化。

三、JavaScript 部分

代码语言:javascript
代码运行次数:0
运行
复制
let data = [];
// 保存翻译文件数据的变量
let translation = {};
// 记录当前语言
let currLang = "zh-cn";
var page = 0;
  • 定义了四个变量:
    • data 用于存储从 all-data.json 文件中获取的项目数据,初始化为空数组。
    • translation 用于存储从 translation.json 文件中获取的翻译数据,初始化为空对象。
    • currLang 用于记录当前页面显示的语言,初始值为 "zh-cn",即中文。
    • page 用于记录当前加载数据的页码,初始值为 0
代码语言:javascript
代码运行次数:0
运行
复制
window.onload = async () => {
  const res1 = await fetch("./js/all-data.json ");
  data = await res1.json();
  const res2 = await fetch("./js/translation.json");
  translation = await res2.json();
  data.slice(0, 15).forEach((item) => {
    $(".list > ul").append(createProjectItem({...item, description: (currLang == "zh-cn"? item.descriptionCN : item.descriptionEN) }));
  });
  document.querySelector(".load-more").addEventListener("click", function () {
    data.slice((page + 1) * 15, (page + 2) * 15).forEach((item) => {
      $(".list > ul").append(createProjectItem({...item, description: (currLang == "zh-cn"? item.descriptionCN : item.descriptionEN) }));
    });
    page++;
    if (page == Math.ceil(data.length / 15) - 1) {
      this.style.display = "none";
    }
  });
};
  • window.onload 事件在页面完全加载后触发,这里使用了异步函数来处理数据获取和页面渲染。
    • 使用 fetch 分别从 ./js/all-data.json./js/translation.json 获取数据,并通过 await 等待数据解析完成,将项目数据存储在 data 中,翻译数据存储在 translation 中。
    • 使用 data.slice(0, 15) 取出前 15 条项目数据,遍历这些数据,调用 createProjectItem 函数生成项目列表项的 HTML 字符串,并将其添加到页面中类名为 listul 元素内。同时根据当前语言 currLang 决定使用 descriptionCN(中文描述)还是 descriptionEN(英文描述)。
    • 为类名为 load-more 的元素添加点击事件监听器。当点击时,根据当前页码 page 取出下一页的 15 条项目数据,同样调用 createProjectItem 函数生成 HTML 字符串并添加到页面中。每次点击后 page 自增 1,如果 page 达到总页数(通过 Math.ceil(data.length / 15) - 1 计算),则隐藏 load-more 按钮。
代码语言:javascript
代码运行次数:0
运行
复制
$(".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: 请在此补充代码实现项目描述的语言切换
  document.querySelectorAll("body > div.container > div.list > ul > li > div.desc > p").forEach((item) => {
    item.textContent =
      currLang == "zh-cn"
       ? data.find(i => i.descriptionEN == item.textContent).descriptionCN
        : data.find(i => i.descriptionCN == item.textContent).descriptionEN;
  });
});
  • 为类名为 lang 的元素添加点击事件监听器。当点击时,根据当前语言 currLang 切换语言状态,更新 lang 元素的文本内容,并将 currLang 设置为相反的语言。
    • 遍历页面中 body 内的所有元素,获取其文本内容,检查 translation 对象中是否有对应的翻译文本,如果有则更新元素的文本内容。
    • 遍历页面中项目描述的段落元素,根据当前语言 currLang,从 data 中查找对应的项目,将描述更新为相应语言的描述。
代码语言:javascript
代码运行次数:0
运行
复制
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>
  `;
}
  • 定义了 createProjectItem 函数,接受一个包含项目信息的对象作为参数,返回一个包含项目信息的 HTML 字符串,用于生成页面上的项目列表项。

四、工作流程▶️

  1. 页面加载时,首先解析 HTML 结构,构建页面的基本布局。
  2. 加载并应用 CSS 样式,使页面具有美观的外观和合适的布局。
  3. 执行 JavaScript 代码:
    • 初始化变量 datatranslationcurrLangpage
    • 页面加载完成后(window.onload 事件触发),使用 fetch 获取项目数据和翻译数据。
    • 解析数据后,先渲染前 15 条项目数据到页面上。
    • 为 “加载更多” 按钮添加点击事件监听器,每次点击加载下一页的 15 条项目数据,并在数据全部加载完后隐藏按钮。
    • 为语言切换按钮添加点击事件监听器,点击时切换页面语言,更新语言切换按钮的文本,并遍历页面元素更新其文本内容为相应语言的翻译文本,同时更新项目描述的语言。
  4. 用户在页面上进行操作(点击 “加载更多” 按钮或语言切换按钮)时,相应的事件监听器会被触发,执行相应的操作,更新页面内容。

测试结果👍

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 准备步骤
  • 目标效果
  • 要求规定
  • 判分标准
  • 通关代码✔️
  • 代码解析📑
    • 一、HTML 部分
    • 二、CSS 部分
    • 三、JavaScript 部分
  • 测试结果👍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档