Bootstrap

结对第二次作业——编程实现

这个作业属于哪个课程2302软件工程
这个作业要求在哪里作业要求
这个作业的目标编程实现结对作业
其他参考文献CSDN 菜鸟教程

目录

1.仓库地址

仓库地址

2.PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划1010
• Estimate• 估计这个任务需要多少时间55
Development开发600500
• Analysis• 需求分析(包括学习新技术)120120
• Design Spec• 生成设计文档3040
• Design Review• 设计复审6060
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)2015
• Design• 具体设计6060
• Coding• 具体编码6060
• Code Review• 代码复审120120
• Test• 测试(自我测试,修改代码,提交修改)120120
Reporting报告180200
• Test Repor• 测试报告6060
• Size Measurement• 计算工作量6060
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划6060
合计15651495

3.项目的访问链接

项目访问链接

4.成品展示

4.1 首页

首页包含网站简介和轮播图,轮播图会循环播放当下热点事件的图片。

首页

首页

首页

首页

4.2 每日赛况

每日赛况页面会以列表的方式展示每个比赛日的所有比赛,点击任意一个比赛可以跳转到其对应的详细赛况。

每日赛况

4.3 详细赛况

详细赛况会以表格的方式展示某个比赛的详细信息,包括选手排名、选手名、分数和分数落后。

详细赛况

详细赛况

详细赛况

4.4 选手排名

选手信息页面分为男、女选手两列表格,分别展示选手的国籍、姓名、性别和出生日期。
选手排名

4.5 奖牌榜

奖牌榜页面主要展示各国的获奖情况,具体包括排名、国家、金牌数、银牌数、铜牌数和奖牌总数。
奖牌榜

5.结对讨论过程

5.1 结对分工

由于我们两都比较擅长后端开发,所以一开始面对前端开发是比较懵的。原计划是做前后端分离开发这个网站,但仔细讨论后发现,在一周时间内要完成这项工作比较困难,但我们也不擅长前端开发,因此决定选择用Html、CSS、JavaScript前端基础三件套来开发这个网站。
网站共包括5个页面:首页、每日赛况、详细赛况、选手信息、奖牌榜
wq负责选手信息页面、奖牌榜页面、博客撰写、服务器部署
lbc负责首页、每日赛况页面和详细赛况页面、博客撰写

5.2 讨论过程截图

讨论1
讨论2
讨论3
讨论4
讨论5
讨论6
讨论7
讨论8
讨论9

6.设计实现过程

6.1 功能描述

功能描述

6.2 实现思路

  • 技术栈:Html、CSS、JavaScript
  • 设计思路:本次的网页实现思路并不复杂,我们一致认为时间有限,来不及用前后端分离的方法来实现,并且作业要求中提到重在展示功能,技术要求次要,所以我们决定用前端三件套来实现首页、选手信息、每日赛况、详细赛况和奖牌榜等若干页面。各个页面以展示数据为主,所以重点在于数据的读取、解析和展示。
  • 数据展示:首先用爬虫从相关网站爬出所需数据(该爬取行为仅用于课程作业中!),然后通过fetch函数来解析、获取json数据,之后在部分用"document.getElementById(‘id’).innerHTML+="来往表格中逐行增加数据。

6.3 困难及解决思路

  • 困难1:数据读取时路径错误,反复测试不同方法,都无法正确读取数据。

  • 解决方案:

    • 方案1:用相对路径来读取数据,data包要存放于根目录上
    • 方案2:调用readFile方法来读取文件数据
  • 困难2:可以读取到json文件后,json数据无法在页面中展示出来

  • 解决方案:将json数据的层次画出来,参考个人实战的读取实现方式,逐层拆解json数据,最后展示成功

7.关键代码展示

7.1 首页

这段代码将五张图片用轮播图的形式进行展示

<div id="slideshow" style="display: flex; background-color: rgb(0, 106, 255);">
        <span style="margin-top: 50px; margin-left: 100px;">
            <label style="font-size: 200px;">&lt;</label>
        </span>
        <span>
            <img class="slideshow" src="1.png" alt="Image 1">
            <img class="slideshow" src="2.png" alt="Image 2">
            <img class="slideshow" src="3.png" alt="Image 3">
            <img class="slideshow" src="4.png" alt="Image 4">
            <img class="slideshow" src="5.png" alt="Image 5">
        </span>
        <span style="margin-top: 50px; margin-right: 100px;">
            <label style="font-size: 200px;">&gt;</label>
        </span>
    </div>
    <script>
        let index = 0;
        const slides = document.getElementsByClassName("slideshow");

        function showSlide(n) {
            if (n >= slides.length) {
                index = 0;
            } else if (n < 0) {
                index = slides.length - 1;
            } else {
                index = n;
            }

            for (let i = 0; i < slides.length; i++) {
                slides[i].style.display = "none";
            }

            slides[index].style.display = "block";
        }

        function nextSlide() {
            showSlide(index + 1);
        }

        function previousSlide() {
            showSlide(index - 1);
        }

        showSlide(index);

        setInterval(nextSlide, 3000);
    </script>

7.2 每日赛况

setMatchName方法通过拼接url的方式实现跳转页面时携带参数

<script>
    function setMatchName(matchName) {
      var url = "./detail.html?name=" + matchName;
      window.location.href = url;
    }
  </script>

这段代码对应每日赛况列表中其中一条赛事信息,点击后调用setMatchName函数将比赛名拼接到url中跳转。同时使用css来设定样式。

<div class="buttom">
      <p></p>
      <buttom title="点击查看详细赛况" class="message" onclick="setMatchName('men 1m springboard')">
        <span class="name">men 1m springboard</span>
        <span class="click">EVENT DETAILS →</span>
      </buttom>
    </div>
.message {
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  border: 1px solid black;
  padding: 10px 100px 10px 20px;
  font-size: 30px;
  cursor: pointer;
  display: block;
  width: 100%;
}
.name {
  margin-right: 600px;
}

.click {
  font-size: 20px;
  color: gray;
  text-align: right;
}
.buttom {
  margin-bottom: 50px;
}

7.3 详细赛况

getName方法用于获取url中的参数

<script>
    function getName(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, "\\$&");
        var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
        }
</script>

这段代码先根据比赛名读取相对应的比赛数据,然后解析这些json格式的数据并将解析结果存入jsonData中。

<script>
    var jsonData;
    var promise = new Promise((resolve, reject) => {
            fetch('../data/results/' + getName('name') + '.json')
            .then(response => response.json())
            .then(data => {
                var jsonStr = JSON.stringify(data);
                jsonData = JSON.parse(jsonStr);
                resolve();
            })
            .catch(error => {
                console.error('读取文件时出错:', error);
                reject(error);
            });
    });
</script>

这段代码通过遍历jsonData中的数据依次读取Rank、FullName、TotalPoints、PointsBehind并将它们用表格的方式进行展示

<script>
    document.getElementById('list').innerHTML =
    "<h2 style='text-decoration: underline; text-decoration-color: rgb(71, 189, 232); color: rgb(71, 189, 232)'>Final</h2>\
        <table>\
            <tr>\
                <td>Overall Rank</td>\
                <td>Athlete</td>\
                <td>Points</td>\
                <td>Points Behind</td>\
            </tr>\
        </table>";
    promise.then(() => {
        jsonData.Heats[0].Results.forEach(element => {
            if(element.PointsBehind == null) {
                document.getElementById('list').innerHTML +=
                "<table>\
                    <tr>\
                        <td>" + element.Rank + "</td>\
                        <td>" + element.FullName + "</td>\
                        <td>" + element.TotalPoints + "</td>\
                        <td>" + "0" + "</td>\
                    </tr>\
                </table>"
            } else {
                document.getElementById('list').innerHTML +=
                "<table>\
                    <tr>\
                        <td>" + element.Rank + "</td>\
                        <td>" + element.FullName + "</td>\
                        <td>" + element.TotalPoints + "</td>\
                        <td>" + element.PointsBehind + "</td>\
                    </tr>\
                </table>"
            }
                
        });
    });
</script>

7.4 选手排名

在CSS样式中设置了响应式布局,并且设置了双栏样式,可以支持男女排行榜


@media screen and (max-width: 800px) {
    /* 响应式布局 - 当屏幕的宽度小于 800 像素时,使两列堆叠而不是并排 */
    .leftcolumn,
    .rightcolumn {
        width: 100%;
        padding: 0;
    }
}

@media screen and (max-width: 400px) {
    /* 响应式布局 - 当屏幕的宽度小于 400 像素时,使导航链接堆叠而不是并排 */
    .topnav a {
        float: none;
        width: 100%;
    }
}
.leftcolumn {
    /* 创建两个不相等的彼此并排的浮动列 */
    /* 左列 */
    float: left;
    width: 50%;
}

.rightcolumn {
    /* 右列 */
    float: left;
    width: 50%;
}

8.心路历程与收获

lbc:通过这次结对编程,我的协作能力又提升了不少,还初步学习了墨刀的使用、原型的设计,以及前端三件套的再学习、json数据的解析获取等等,和队友的合作也非常的轻松愉快,是一次体验非常好且收获满满的编程经历。
wq: 这次结对编程对我们来说算是个不小的挑战,要离开我们的后端舒适区,使用纯前端的方式实现网站。面对新要求和新难题,我们不慌不乱,逐个把复杂问题拆解为简单问题,并逐一攻破,还很有成就感的,也收获了很多编程技巧。

9.结对评价

lbc:wq的团队意识很强,会时刻想着自己的队友,尽自己所能去帮助队友,而且善于交流,想法又多又好,让我感到工作轻松了不少。
wq: lbc的学习能力特别强,即使面对不熟悉的前端三件套,他也能很快学会并上手使用,在json数据读取和解析方面帮了我很多忙,我很感激他。在团队合作中,交给他的任务总是能很快地完成,并提出不错的优化建议,让我感觉十分地给力。

;