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

222200115吴俊斌 2024-10-01 00:00:16
这个作业属于哪个课程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>

遇到的困难及解决方法

困难描述

  1. 详细赛况难以实现
  2. 如何获取数据
  3. 如何实现按钮的跳转
  4. 如何传递信息在不同页面

解决尝试+是否解决

  • 问了万能的gpt,已解决

    有何收获

前端的知识非常错综复杂,还是有很大的进步空间的。

组队总结

结对感受

此次编程任务十分的刻苦艰巨,

队友评价

林宇:都好
林逸宏:很好
吴俊斌:炒鸡好

合作截图

敲定项目合作及分工

在这里插入图片描述

在这里插入图片描述

PSP表格

PSPProcess Stages预估耗时实际耗时
Planning计划分钟分钟
• Estimate• 估计这个任务需要多少时间1010
• Analysis• 需求分析 (包括学习新技术)300900
• Design Spec• 生成设计文档2020
• Design• 具体实现400600
• Test• 测试(自我测试,修改界面,提交修改)6060
Reporting报告6060
合计8501650
...全文
152 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

239

社区成员

发帖
与我相关
我的任务
社区管理员
  • FZU_SE_teacherW
  • 助教赖晋松
  • D's Honey
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧