110
社区成员
这个作业属于哪个课程 | FZU_SE_teacherW_4 |
---|---|
这个作业要求在哪里 | 结对第二次作业——编程实现 |
结对学号 | 222200233,222200215 |
这个作业的目标 | PSP表格,实现原型中的功能,web |
其他参考文献 | 《构建之法》 |
链接:CodeArt项目地址
PSP | Personal Software Process Stages | 预估耗时(小时) | 实际耗时(小时) |
---|---|---|---|
Planning | 计划 | 1 | 1 |
Estimate | 估计这个任务需要多少时间 | 6 | 18 |
Development | 开发 | 6 | 4 |
Analysis | 需求分析 (包括学习新技术) | 1 | 6 |
Design Spec | 生成设计文档 | 1 | 1 |
Design Review | 设计复审 | 1 | 1 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 0.5 | 0.5 |
Design | 具体设计 | 1 | 1 |
Coding | 具体编码 | 5 | 5 |
Code Review | 代码复审 | 0.5 | 0.5 |
Test | 测试(自我测试,修改代码,提交修改) | 3 | 3 |
Reporting | 报告 | 1 | 1 |
Test Repor | 测试报告 | 1 | 1 |
Size Measurement | 计算工作量 | 1 | 1 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 1 | 1 |
合计 | 30 | 45 |
链接:http://110.41.160.232/a/index.html
这是主界面,上面是标签栏,每个界面都有,可以跳转到任意的页面
在结对开发中,双方进行交流是非常重要的事情。我们大部分的交流都是在线上进行的,我们会讨论网页的实现方案,讨论如何租用服务器进行部署。
但是线上交流的效率毕竟不如线下面对面交流,所以我们会积极利用上机课,和其他课程的课余时间当面探讨代码的技术实现方案和git协作过程。
由于技术限制和我们设计的原型功能需求不大,所以这次作业我们采取了纯前端的方式来实现。
我们经过讨论选择使用HTML 作为Web的结构化的框架。并且通过CSS来进行设计样式尽量还原原型设计,以及通过JavaScript实现交互功能,包括轮播图,日期切换,以及
鼠标选择加粗显示等功能。 网页展示的奖牌榜,对阵图,
以我们实现的网页的首页为例子,首先我们通过之前的原型确定功能:比如导航栏、图片轮播。然后使用HTML和CSS构建网页的基本框架,编写HTML结构,主容器.main
导航栏.top,包含链接到其他页面的导航项,以及图片轮播区域。然后编写JavaScript脚本函数来实现图片轮播等功能。其他页面实现的基本方式差不多。
每日赛程的数据来自第一次个人实战爬虫爬来的json数据。我们使用 XMLHttpRequest 从本地 JSON 文件加载奖牌数据。然后将 JSON 字符串解析为 JavaScript 对象来使用。
clickR 函数用于实现图片轮播的核心逻辑,每次调用时,都会将当前图片索引 num 加一,并更新图片源 Oimg.src 为数组 arrUrl 中的下一张图片。
function clickR() {
num++; // 增加当前图片的索引
if (num == arrUrl.length) { // 如果当前索引等于图片数组的长度
num = 0; // 重置索引为0,实现循环播放
}
Oimg.src = arrUrl[num]; // 更新图片源为下一张图片
turnactive(num); // 调用函数,激活对应的指示器
}
鼠标悬停和离开事件
Oimg.onmouseover = function () {
clearInterval(timer); // 鼠标悬停时,清除定时器,停止轮播
};
Oimg.onmouseout = function () {
timer = setInterval(clickR, 2000); // 鼠标离开时,重新设置定时器,继续轮播
};
为每个指示器添加事件
for (var i = 0; i < arrUrl.length; i++) {
Oli[i].index = i; // 为每个指示器设置索引
Oli[i].onmouseover = function () {
this.getElementsByTagName('img')[0].style.display = 'block'; // 显示对应的小图
this.getElementsByTagName('img')[0].src = arrUrl[this.index]; // 更新小图的图片源
clearInterval(timer); // 清除定时器,停止轮播
};
Oli[i].onmouseout = function () {
this.getElementsByTagName('img')[0].style.display = 'none'; // 隐藏小图
timer = setInterval(clickR, 2000); // 重新设置定时器,继续轮播
};
Oli[i].onclick = function () {
Oimg.src = arrUrl[this.index]; // 点击指示器时,跳转到对应的图片
turnactive(this.index); // 激活对应的指示器
}
}
激活指示器的函数 turnactive
function turnactive(nu) {
for (var i = 0; i < arrUrl.length; i++) {
Oli[i].className = ''; // 移除所有指示器的激活状态
}
Oli[nu].className = 'active'; // 激活当前指示器
}
处理从 URL 参数中获取的比赛数据,并更新到 HTML 页面。详细思路见注释
<script>
// 获取当前页面的URL
const urlParams = new URLSearchParams(window.location.search);
// 获取名为data的参数值
const matchDetails = urlParams.get('data');
// 对获取到的值进行JSON解析(因为传递过来之前进行了JSON.stringify)
const matchData = JSON.parse(decodeURIComponent(matchDetails));
console.log(matchData); // 输出: { name: "John", age: "30" }
// 更新比赛数据到HTML页面
const matchElement = document.getElementById('matchData');
matchElement.querySelector('.bj-top').textContent = `${matchData.disciplineName} - 比赛 ${matchData.phaseName}`;
matchElement.querySelector('.bj-top1').textContent = matchData.statusDescription;
const team1Element = matchElement.querySelectorAll('.bj-main1')[0];
const team1Logo = team1Element.querySelector('img');
const team1Name = team1Element.querySelector('.bj-main2 div');
const team1Country = team1Element.querySelector('.bj-e');
team1Logo.src = `./images/${matchData.competitors[0].noc}.png`;
team1Name.textContent = matchData.competitors[0].noc;
team1Country.textContent = matchData.competitors[0].name;
team1Element.querySelector('div[style="font-size:70px ;"]').textContent = matchData.competitors[0].results.mark;
const team2Element = matchElement.querySelectorAll('.bj-main1')[1];
const team2Logo = team2Element.querySelector('img');
const team2Name = team2Element.querySelector('.bj-main2 div');
const team2Country = team2Element.querySelector('.bj-e');
team2Logo.src = `./images/${matchData.competitors[1].noc}.png`;
team2Name.textContent = matchData.competitors[1].noc;
team2Country.textContent = matchData.competitors[1].name;
team2Element.querySelector('div[style="font-size:70px ;"]').textContent = matchData.competitors[1].results.mark;
const matchElement1 = document.getElementById('aa');
const team1Element1 = matchElement1.querySelectorAll('.bj-main2')[0];
const team1Logo1 = team1Element1.querySelector('img');
const team1Name1 = team1Element1.querySelector('div');
team1Logo1.src = `./images/${matchData.competitors[0].noc}.png`;
team1Name1.textContent = matchData.competitors[0].noc;
const team1Element2 = matchElement1.querySelectorAll('.bj-main2')[1];
const team1Logo2 = team1Element2.querySelector('img');
const team1Name2 = team1Element2.querySelector('div');
team1Logo2.src = `./images/${matchData.competitors[1].noc}.png`;
team1Name2.textContent = matchData.competitors[1].noc;
const tabs = document.querySelectorAll('.topright1 div');
const chu = document.getElementById('chu');
const xq = document.getElementById('xq');
tabs.forEach(tab => {
tab.addEventListener('click', function () {
tabs.forEach(item => item.classList.remove('active', 'selected'));
this.classList.add('active', 'selected');
if (this.textContent === '比赛详情') {
// 在这里可以实现切换到比赛详情页面的逻辑,例如通过修改页面内容或进行页面跳转
console.log('切换到比赛详情页面');
chu.style.display = 'none';
xq.style.display = 'block';
} else {
chu.style.display = 'block';
xq.style.display = 'none';
}
});
});
displayPage()
包含两个 JavaScript 函数 displayPage 和 displayPage1,它们的作用是将存储在 JSON 文件中的数据动态加载并显示到 HTML 表格中
function displayPage() {
const table = document.getElementById('table');
table.innerHTML = '';
// 使用 XMLHttpRequest 加载 JSON 文件
const xhr = new XMLHttpRequest();
xhr.open('GET', './json/jp.json', false);
xhr.send(null);
const data = JSON.parse(xhr.responseText);
// 创建表头
const headerRow = table.insertRow(-1);
for (let j = 0; j < 5; j++) {
const cell = headerRow.insertCell(-1);
if (j === 0) {
cell.textContent = 'NO.姓名';
} else if (j === 1) {
cell.textContent = '位置';
} else if (j === 2) {
cell.textContent = '上场时间';
} else if (j === 3) {
cell.textContent = '进球';
} else if (j === 4) {
cell.textContent = '铜失球';
}
}
headerRow.style.border = 'none';
for (let i = 0; i < data.length; i++) {
const row = table.insertRow(-1);
const item = data[i];
for (let j = 0; j < 5; j++) {
const cell = row.insertCell(-1);
if (j === 0) {
cell.textContent = i + 1;
} else if (j === 1) {
// 添加图片
const img = document.createElement('img');
img.src = "./images/" + item.organisation + ".png"; // 假设图片的URL存储在item.organisation字段中
img.alt = item.longDescription; // 设置图片的alt文本
img.style.width = '50px'; // 设置图片宽度
img.style.height = 'auto'; // 设置图片高度
img.style.verticalAlign = 'middle'; // 图片垂直居中
// 创建一个容器来包含图片和文字
const container = document.createElement('div');
container.style.display = 'flex';
container.style.alignItems = 'center'; // 垂直居中
container.appendChild(img);
container.appendChild(document.createTextNode(item.longDescription)); // 添加描述文本
cell.appendChild(container);
} else if (j === 2) {
cell.textContent = item.gold
} else if (j === 3) {
cell.textContent = item.silver;
} else if (j === 4) {
cell.textContent = item.bronze;
}
}
}
}
displayPage1()
function displayPage1() {
const table = document.getElementById('table1');
table.innerHTML = '';
// 使用 XMLHttpRequest 加载 JSON 文件
const xhr = new XMLHttpRequest();
xhr.open('GET', './json/jp.json', false);
xhr.send(null);
const data = JSON.parse(xhr.responseText);
for (let i = 0; i < data.length; i++) {
const row = table.insertRow(-1);
const item = data[i];
for (let j = 0; j < 5; j++) {
const cell = row.insertCell(-1);
if (j === 0) {
cell.textContent = i + 1;
} else if (j === 1) {
// 添加图片
const img = document.createElement('img');
img.src = "./images/" + item.organisation + ".png"; // 假设图片的URL存储在item.organisation字段中
img.alt = item.longDescription; // 设置图片的alt文本
img.style.width = '50px'; // 设置图片宽度
img.style.height = 'auto'; // 设置图片高度
img.style.verticalAlign = 'middle'; // 图片垂直居中
// 创建一个容器来包含图片和文字
const container = document.createElement('div');
container.style.display = 'flex';
container.style.alignItems = 'center'; // 垂直居中
container.appendChild(img);
container.appendChild(document.createTextNode(item.longDescription)); // 添加描述文本
cell.appendChild(container);
} else if (j === 2) {
cell.textContent = item.gold
} else if (j === 3) {
cell.textContent = item.silver;
} else if (j === 4) {
cell.textContent = item.bronze;
}
}
}
}
</script>
</body>
<body>
<div class="main">
<div class="top">
<div style="width: 10%;margin-left: 30px;"><a href="./index.html">主页面</a></div>
<div class="topright">
<div><a href="./jp.html">奖牌榜单</a></div>
<div><a href="./sc.html">每日赛程</a></div>
<div class="ad"><a href="./dz.html">对战表</a></div>
</div>
</div>
<div class="bottom">
<div class="border1">
<div class="border2">
<div>1/4决赛</div>
<div>半决赛</div>
<div>总决赛</div>
</div>
<div class="border3">
<div>
<ul>
<li class="li aatop">
<div class="li-main aas ">
<div class="aa ">
<div class="aa1 ">
<img style="width: 50px;margin-right: 5px;" src="./images/FRA.png" alt="">法国
</div>
<div>1</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/ARG.png"
alt="">阿根廷
</div>
<div>0</div>
</div>
</div>
</li>
<li class="li">
<div class="li-main aax">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/EGY.png" alt="">埃及
</div>
<div>1</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/TUN.png"
alt="">突尼斯
</div>
<div>1</div>
</div>
</div>
</li>
<li class="li aatop">
<div class="li-main aas">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/MAR.png"
alt="">摩洛哥
</div>
<div>4</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/USA.png" alt="">美国
</div>
<div>0</div>
</div>
</div>
</li>
<li class="li">
<div class="li-main aax">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/CHN.png" alt="">中国
</div>
<div>0</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/JPN.png" alt="">日本
</div>
<div>7</div>
</div>
</div>
</li>
</ul>
</div>
<div>
<ul>
<li class="li aatop1">
<div class="li-main aas1">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/FRA.png" alt="">法国
</div>
<div>ATE</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/EGY.png" alt="">埃及
</div>
<div></div>
</div>
</div>
</li>
<li class="li">
<div class="li-main aax1">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/MAR.png"
alt="">摩洛哥
</div>
<div>1</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/JPN.png" alt="">日本
</div>
<div>0</div>
</div>
</div>
</li>
</ul>
</div>
<div>
<ul>
<li class="li">
<div style="margin-top: 140px;" class="jin">
金牌赛
</div>
<div class="li-main">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/FRA.png" alt="">法国
</div>
<div>0</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/MAR.png"
alt="">摩洛哥
</div>
<div>1</div>
</div>
</div>
<div style="margin-top: 100px;" class="jin">
铜牌赛
</div>
<div class="li-main">
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/MAR.png"
alt="">摩洛哥
</div>
<div>6</div>
</div>
<div class="aa">
<div class="aa1">
<img style="width: 50px;margin-right: 5px;" src="./images/EGY.png" alt="">埃及
</div>
<div>0</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</body>
心路历程
在接触结对开发项目之初,我们两人都感到了不小的压力。真正的协作开发和平时的个人完成任务有着很大 的区别。起初,我们对前端和后端都不是十分了解,我们对于如何分配任务、如何有效沟通以及如何解决技术问题都显得有,额,完全没有头绪。在时间开发过程中,我们也遇到了诸如华为云无法邀请队友、分支合并冲突等问题,这些问题都十分令人恼火。然而,随着时间的推进和deadline的逼近,我们逐渐找到了合作的节奏,开始试着解决问题。我们进一步学会了使用Git,更加了解如何进行结对编程,,如何使用html,JavaScript来编写网页,并通过不断的实践,提高了我们的编程能力和团队协作能力。最终,我们成功完成了项目的基本要求,这些并进一步做出了详细赛况的前端部分。
收获
通过这次结对开发项目,我们获得了宝贵的实践经验。首先,我们在技术层面上有了显著的提升,特别是在前端开发和网页设计方面。我们学会了如何如何使用html,JavaScript来编写网页。其次,我们在团队协作方面也有了深刻的体会。我们认识到了沟通的重要性,学会了倾听对方的意见,并通过协商达成共识。这次经历也让我们意识到了代码规范和文档编写的重要性,这对于维护项目和提高开发效率至关重要。最后,我们还学会了如何进行项目规划和时间管理,这对于我们未来的职业生涯无疑是一笔宝贵的财富。
蔡文韬: 他在前端开发方面有着扎实的技术基础,特别是在JavaScript上,他能够快速地解决各种奇怪的问题。 他对待协作的任务的态度很认真。大部分和编程和部署问题都是他解决的,
并且易于沟通,合作非常愉快。
汪明昊:他擅长处理各种杂项问题,包括构建仓库,分配协作任务。在遇到困难时,总是耐心地解决问题。非常具有团队精神。