结对第二次作业——编程实现
| 这个作业属于哪个课程 | FZU_SE_teacherW_4 |
|---|---|
| 这个作业要求在哪里 | 结对第二次作业——编程实现-CSDN社区 |
| 结对学号 | 052205124,222200115,222100422 |
| 这个作业的目标 | 了解前端知识,部署网页 |
| 其他参考文献 | 《构建之法》 |
目录
- 基本要求
- 仓库链接 代码规范链接 云服务器链接
- 功能分析
- 1. 系统设计
- 1.1 模块化设计
- 1.2 系统架构
- 2. 系统合理性分析
- 2.1 可扩展性
- 2.2 用户体验
- 模型设计
- 设计过程
- 结果汇报
- 设计思路
- 首页
- 奖牌榜
- 竞赛日程
- 足球对阵
- 代码说明
- 首页跳转实现
- 首页下方布局
- 奖牌榜所有国家排名实现
- 日期选择器
- 点击事件以及数据获取
- 遇到的困难及解决方法
- 困难描述
- 解决尝试+是否解决
- 有何收获
- 组队总结
- 结对感受
- 队友评价
- 合作截图
- PSP表格
基本要求
仓库链接 代码规范链接 云服务器链接
- 依照下方规范,代码规范在项目中
代码规范地址
功能分析
1. 系统设计
1.1 模块化设计
网页采用模块化设计,将不同的功能模块进行独立开发和维护。主要模块包括:
- 首页模块:提供跳转到其他页面的接口。
- 赛事日程模块:展示每天的比赛日程、赛程安排和比赛结果。
- 奖牌榜模块:实时更新各国奖牌数,包括金银铜奖牌的分布。
- 对阵表:展示足球比赛的对阵表信息。
- 详细赛况:展示某一场比赛的详细数据
1.2 系统架构
- 由于时间技术有限,本次作业采用了纯前端的技术实现,数据通过js调用json文件来实现数据获取,具体代码只以采用了基本的三件套html、css、js。
2. 系统合理性分析
2.1 可扩展性
- 模块化设计使得后期功能扩展和升级变得更加简单以及易于维护。例如,系统可以随时新增一个新的功能模块或其他模块,而不影响现有网页功能的运行。以确保系统能长期运行并且适应未来需求。
2.2 用户体验
- 用户体验方面:由于使用的纯前端数据,某些html的展现是在js使用了async()获取数据后展现的,容易让用户感觉卡顿之类的,为了优化体验,我们添加了某些图片使网页更具美感。
模型设计
设计过程
- 首先进行需求分析,决定实现的功能
- 设计网页由几个部分组成。
- 具现化每个页面,以及链接关系
结果汇报
设计思路
首页
在首页支持四个主要功能模块的相互跳转

在下方也提供了更显眼的页面。

奖牌榜
实现了可滑动奖牌榜,拥有全面的国家获奖信息,包括国旗等图片形式

- 并且在左上方提供了返回按钮
竞赛日程
- 实现了每日项目的数据

实现了日期选择,例如这里选择八月1日

点击查看详情

包括初赛名单和比赛详情


足球对阵

- 足球对阵图,同时鼠标移入呈现动效

代码说明
首页跳转实现
<div class="button-container">
<div class="round-button" onclick="toggleDropdown(event)">
<img src="./images/菜单.png" alt="">
</div>
<img src="./images/logo.svg" alt="">
<button class="round-button">
<img src="./images/搜索.png" alt="">
</button>
<div class="dropdown" id="dropdownMenu">
<a href="../src/Medals.html">奖牌榜</a>
<a href="./daily-page.html">每日赛程</a>
<a href="../src/FootballVS.html">对阵表</a>
<a href="./learnmore-page.html">了解更多</a>
</div>
</div>
<h1>2024年巴黎奥运会</h1>
</div>
.................................
<style>
.btn1 {
.round-button {
width: 80px;
height: 80px;
border: none;
border-radius: 50%;
cursor: pointer;
background-color: #fff;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
.round-button img {
width: 50%;
height: 50%;
}
.tran-button {
width: 400px;
height: 600px;
border: none;
border-radius: 5%;
cursor: pointer;
overflow: hidden;
display: flex;
justify-content: space-around;
align-items: center;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
margin-top: 50px;
margin-left: 10px;
margin-right: 10px;
}
.tran-button img {
width: 100%;
height: 100%;
}
</style>
首页下方布局
<div class="tran-button" style="background: url(./images/medalsbg.png) no-repeat; background-size: 100% 100%;">
<h1>
奖牌榜
</h1>
</div>
<div class="tran-button" style="background: url(./images/homebg2.png) no-repeat; background-size: 100% 100%;">
<h1>
每日赛程
</h1>
</div>
<div class="tran-button" style="background: url(./images/homebg.png) no-repeat; background-size: 100% 100%;">
<h1>
对阵表
</h1>
</div>
<div class="tran-button" style="background: url(./images/homebg4.png) no-repeat; background-size: 100% 100%;">
<h1>
了解更多
</h1>
</div>
</div>
- 巧妙地应用flex等样式,通过调整margin-left和right等参数控制图片的相对布局
奖牌榜所有国家排名实现
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>Medals</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="main">
<div class="button-container">
<div class="round-button" onclick="toggleDropdown(event)">
<img src="../hometest/images/菜单.png" alt="">
</div>
<button class="round-button">
<img src="../hometest/images/搜索.png" alt="">
</button>
<div class="dropdown" id="dropdownMenu">
<a href="./Medals.html">奖牌榜</a>
<a href="../hometest/daily-page.html">每日赛程</a>
<a href="./FootballVS.html">对阵表</a>
<a href="../hometest/learnmore-page.html">了解更多</a>
</div>
</div>
<div>
<img src="./image/head.png" alt="head" class="flex-head">
</div>
<br>
<table>
<thead>
<tr class="flex-container">
<th><span class="flex-text">顺序</span></th>
<th><span class="flex-text">FLAG</span></th>
<th class="col2"><span class="flex-text">NOC</span></th>
<th><img src="./image/gold.png" alt="gold" class="flex-image"></th>
<th><img src="./image/sliver.png" alt="sliver" class="flex-image"></th>
<th><img src="./image/bronze.png" alt="bronze" class="flex-image"></th>
<th><img src="./image/total.png" alt="total" class="flex-image"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in rank" class="flex-container">
<td><span class="flex-number">{{item.rank}} </span></td>
<td><img :src="item.img" :alt="flag" class="flex-flag"></td>
<td class="col2"><span class="flex-text">{{item.countryname}} </span></td>
<td><span class="flex-number">{{item.gold}} </span></td>
<td><span class="flex-number">{{item.silver}} </span></td>
<td><span class="flex-number">{{item.bronze}} </span></td>
<td><span class="flex-number">{{item.count}} </span></td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
$(document).ready(function () {
$.getJSON("./rank.json", function (result, status) {
var app = new Vue({
el: '#main',
data: {
rank: result
}
})
})
})
function toggleDropdown(event) {
event.stopPropagation(); // 阻止事件冒泡
const dropdown = document.getElementById('dropdownMenu');
dropdown.classList.toggle('show');
}
// 点击页面其他地方时关闭下拉菜单
window.onclick = function (event) {
if (!event.target.closest('.round-button')) {
const dropdown = document.getElementById('dropdownMenu');
if (dropdown.classList.contains('show')) {
dropdown.classList.remove('show');
}
}
}
</script>
</html>
通过抓包先爬取网页数据处理成img.json文件
内层容器,使用 flex 布局,将元素横向排列,然后获取国家的具体信息
日期选择器
display: none;
position: absolute;
top: 150px;
left: 20%;
transform: translateX(-50%);
grid-template-columns: repeat(7, 1fr);
/* grid布局 */
gap: 10px;
text-align: center;
max-width: 500px;
width: 100%;
border-color: #a29e9e;
border-width: 2px;
border-style: solid;
border-radius: 10px;
box-shadow: 2px 4px 8px rgba(12, 10, 10, 0.1);
padding: 3px;
/* z-index: 100; */
/* 堆叠顺序? */
}
/* 日期 */
.day {
padding: 10px;
border: 1px solid #000;
border-radius: 15px;
cursor: pointer;
transition: background-color 0.3s ease, color 0.3s ease;
/* 过渡视觉 */
font-size: 18px;
}
.day.active {
background-color: black;
color: white;
}
.day:hover {
background-color: black;
color: white;
}
.header {
font-weight: bold;
font-size: 18px;
}
#toggle-calendar {
/* 切换日历类 */
height: 50px;
display: inline-block;
cursor: pointer;
font-size: 30px;
text-align: center;
margin: 20px auto;
font-weight: bold;
padding: 10px;
border: 2px solid #000;
border-radius: 5px;
transition: background-color 0.3s ease, color 0.3s ease;
}
#toggle-calendar:hover {
background-color: black;
color: white;
}
#data-display {
margin-top: 10px;
text-align: center;
}
<div class="calendar" id="calendar">
<div class="header">一</div>
<div class="header">二</div>
<div class="header">三</div>
<div class="header">四</div>
<div class="header">五</div>
<div class="header">六</div>
<div class="header">日</div>
<div></div>
<div></div>
<div class="day" data-date="7月24日">24<br>7月</div>
<div class="day" data-date="7月25日">25<br>7月</div>
<div class="day" data-date="7月26日">26<br>7月</div>
<div class="day" data-date="7月27日">27<br>7月</div>
<div class="day" data-date="7月28日">28<br>7月</div>
<div class="day" data-date="7月29日">29<br>7月</div>
<div class="day" data-date="7月30日">30<br>7月</div>
<div class="day" data-date="7月31日">31<br>7月</div>
<div class="day" data-date="8月01日">01<br>8月</div>
<div class="day" data-date="8月02日">2<br>8月</div>
<div class="day" data-date="8月03日">3<br>8月</div>
<div class="day" data-date="8月04日">4<br>8月</div>
<div class="day" data-date="8月05日">5<br>8月</div>
<div class="day" data-date="8月06日">6<br>8月</div>
<div class="day" data-date="8月07日">7<br>8月</div>
<div class="day" data-date="8月08日">8<br>8月</div>
<div class="day" data-date="8月09日">9<br>8月</div>
<div class="day" data-date="8月10日">10<br>8月</div>
<div class="day" data-date="8月11日">11<br>8月</div>
<div class="day" data-date="8月12日">12<br>8月</div>
</div>
通过button属性实现
并且将选择日期后的显示栏变黑,字体变白。
点击事件以及数据获取
// 获取页面元素
const toggleCalendar = document.getElementById('toggle-calendar'); // 切换日历的按钮
const calendar = document.getElementById('calendar'); // 日历容器
const days = document.querySelectorAll('.day'); // 所有日期元素
const dataDisplay = document.getElementById('data-display'); // 显示比赛数据的区域
// 设置当前选中的日期为7月24日,并标记为活动状态
let currentSelectedDay = document.querySelector('.day[data-date="7月24日"]');
currentSelectedDay.classList.add('active'); // 添加活动样式
toggleCalendar.textContent = '7月24日'; // 更新显示的日期
// 点击切换日历的按钮时的事件处理
toggleCalendar.addEventListener('click', function (event) {
// 切换日历的显示状态
calendar.style.display = calendar.style.display === 'none' ? 'grid' : 'none';
event.stopPropagation(); // 阻止事件冒泡
});
// 点击页面其他区域时,隐藏日历
document.addEventListener('click', function () {
calendar.style.display = 'none'; // 隐藏日历
});
// 点击日历时,阻止事件冒泡,防止隐藏日历
calendar.addEventListener('click', function(event) {
event.stopPropagation();
});
// 根据日期获取比赛数据的异步函数
async function getDataForDate(date) {
// 格式化文件名,例如将"7月24日"转换为"724.json"
const filename = date.replace("月", "").replace("日", "") + ".json";
try {
const response = await fetch(`dates/${filename}`);
// fetch用于进行网络请求的API请求对应日期的JSON数据
if (!response.ok) throw new Error('网络错误');
// 如果响应不正常,抛出错误
const jsonData = await response.json();
// 解析JSON数据
if (jsonData.code !== 1) return '无数据';
// 检查返回的状态码
// 格式化返回的数据,生成比赛信息的HTML结构
return jsonData.data.map(item => {
// if(number(item.countryScore1) >= number(item.countryScore2)){
// } else if(number(item.countryScore1) < number(item.countryScore2)){
// }
return `<div
class="match" data-date="${date}"
data-competition="${item.competitionName}"
data-score="${item.countryScore1}:${item.countryScore2}"
onclick="goToDetails('${date}', '${item.competitionName}',
'${item.countryScore1}:${item.countryScore2}')">
${item.time} - ${item.competitionName}:
${item.countryName1} ${item.countryScore1} :
${item.countryName2} ${item.countryScore2}
</div>`;
}).join('<br>'); // 使用 <br> 换行显示
} catch (error) {
console.error(error); // 输出错误信息
return '无法加载数据'; // 返回错误提示
}
}
// 跳转到比赛详情页面的函数
function goToDetails(date, competition, score) {
// 创建跳转的URL,包含日期、比赛名称和分数作为查询参数
const url = `details.html?date=${encodeURIComponent(date)}&competition=${encodeURIComponent(competition)}&score=${encodeURIComponent(score)}`;
window.location.href = url; // 跳转到详情页
}
// 获取初始日期的数据并显示,当DOM内容加载完成后执行
document.addEventListener('DOMContentLoaded', async () => {
const initialDate = '7月24日'; // 初始日期
const data = await getDataForDate(initialDate); // 获取初始日期的数据
dataDisplay.innerHTML = data; // 显示内容
});
// 为每个日期添加点击事件
days.forEach(day => {
day.addEventListener('click', async function () {
if (currentSelectedDay) {
currentSelectedDay.classList.remove('active'); // 清除之前的选中样式
}
day.classList.add('active'); // 添加当前日期的选中样式
currentSelectedDay = day; // 更新当前选中的日期
toggleCalendar.textContent = day.dataset.date; // 更新显示的当前日期
calendar.style.display = 'none'; // 点击后隐藏日历
// 显示数据
const date = day.dataset.date; // 获取当前日期
const data = await getDataForDate(date); // 获取数据
dataDisplay.innerHTML = data; // 使用 innerHTML 显示内容
});
});
function toggleDropdown(event) {
event.stopPropagation(); // 阻止事件冒泡
const dropdown = document.getElementById('dropdownMenu');
dropdown.classList.toggle('show');
}
// 点击页面其他地方时关闭下拉菜单
window.onclick = function (event) {
if (!event.target.closest('.round-button')) {
const dropdown = document.getElementById('dropdownMenu');
if (dropdown.classList.contains('show')) {
dropdown.classList.remove('show');
}
}
}
</script>
遇到的困难及解决方法
困难描述
- 详细赛况难以实现
- 如何获取数据
- 如何实现按钮的跳转
- 如何传递信息在不同页面
解决尝试+是否解决
- 问了万能的gpt,已解决
有何收获
前端的知识非常错综复杂,还是有很大的进步空间的。
组队总结
结对感受
此次编程任务十分的刻苦艰巨,
队友评价
林宇:都好
林逸宏:很好
吴俊斌:炒鸡好
合作截图
敲定项目合作及分工


PSP表格
| PSP | Process Stages | 预估耗时 | 实际耗时 |
|---|---|---|---|
| Planning | 计划 | 分钟 | 分钟 |
| • Estimate | • 估计这个任务需要多少时间 | 10 | 10 |
| • Analysis | • 需求分析 (包括学习新技术) | 300 | 900 |
| • Design Spec | • 生成设计文档 | 20 | 20 |
| • Design | • 具体实现 | 400 | 600 |
| • Test | • 测试(自我测试,修改界面,提交修改) | 60 | 60 |
| Reporting | 报告 | 60 | 60 |
| 合计 | 850 | 1650 |
相关推荐
PairProject:W班软件工程实践结对第二次作业仓库
结对第二次作业-顶会热词统计的实现 为了不遗漏作业内容,这里有一个清单检查表方便同学们快速检阅。 fork仓库,和伙伴商讨如何通过github协作/代码规范等 编程实现 功能一,操作爬取的论文列表 功能二,爬取结果分析展示 功能三,爬取论文信息(附加功能,实现有附加分) 其他附加功能 部署 发布发布版本,发起拉取请求 撰写博客,在预先之前提交一份博客 包含作业描述和目录 核对评分标准 上一次结对作业中,大家都和小伙伴完成了原型的设计,那么现在再联合小伙伴动手实现原型中的部分功能吧。采用网络技术来实现原型中的功能。 一,作业内容 1.基础功能 功能1:对已爬取的论文列表进行操作 可对论文列表进行删除; 可对论文列表进行查询详细信息(支持模糊查询,查询结果的展示,排序等功能可自行设计); 功能2:分析已爬取到的论文信息,提取top10个热门领域或热门研究方向 形成如关键字图谱之类直观的查看方式
基于Python语言的P4程序结对作业设计源码
该项目是一款基于Python语言的P4程序结对作业设计源码,总文件量为114个,其中Python源文件57个,JSON配置文件24个,P4配置文件11个,Markdown文档8个,PNG图像文件3个,许可证文件1个,以及多个Makefile文件。该项目旨在通过结对作业的形式,提升编程能力和团队合作精神。
软件工程实践结对作业二.md
软件工程实践结对作业二.md
2020级计算机系软件工程第二次结对编程作业.zip
2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip
结对编程技术与策略pdf
介绍结对编程方法、技术和策略。包括结对编程定义、好处。结对策略与组织方法,存在的问题与注意事项等


