ci: enforce code formatting checks for backend and frontend (#1536)

This commit is contained in:
greatmengqi
2026-03-29 15:34:38 +08:00
committed by GitHub
parent 06a623f9c8
commit 084dc7e748
105 changed files with 8253 additions and 7369 deletions
@@ -1 +1,4 @@
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>">
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>"
/>
@@ -1,365 +1,385 @@
<!DOCTYPE html>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>江苏城市足球联赛2025赛季 | 苏超联赛第一季</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800;900&family=Oswald:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>">
</head>
<body>
<link rel="stylesheet" href="css/style.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800;900&family=Oswald:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"
/>
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚽</text></svg>"
/>
</head>
<body>
<!-- 加载动画 -->
<div class="loader">
<div class="loader-content">
<div class="football"></div>
<div class="loader-text">加载中...</div>
</div>
<div class="loader-content">
<div class="football"></div>
<div class="loader-text">加载中...</div>
</div>
</div>
<!-- 导航栏 -->
<nav class="navbar">
<div class="container">
<div class="nav-brand">
<div class="logo">
<div class="logo-ball"></div>
<span class="logo-text">苏超联赛</span>
</div>
<div class="league-name">江苏城市足球联赛2025赛季</div>
</div>
<div class="nav-menu">
<a href="#home" class="nav-link active">首页</a>
<a href="#teams" class="nav-link">球队</a>
<a href="#fixtures" class="nav-link">赛程</a>
<a href="#standings" class="nav-link">积分榜</a>
<a href="#stats" class="nav-link">数据</a>
<a href="#news" class="nav-link">新闻</a>
</div>
<div class="nav-actions">
<button class="btn-theme-toggle">
<i class="fas fa-moon"></i>
</button>
<button class="btn-menu-toggle">
<i class="fas fa-bars"></i>
</button>
</div>
<div class="container">
<div class="nav-brand">
<div class="logo">
<div class="logo-ball"></div>
<span class="logo-text">苏超联赛</span>
</div>
<div class="league-name">江苏城市足球联赛2025赛季</div>
</div>
<div class="nav-menu">
<a href="#home" class="nav-link active">首页</a>
<a href="#teams" class="nav-link">球队</a>
<a href="#fixtures" class="nav-link">赛程</a>
<a href="#standings" class="nav-link">积分榜</a>
<a href="#stats" class="nav-link">数据</a>
<a href="#news" class="nav-link">新闻</a>
</div>
<div class="nav-actions">
<button class="btn-theme-toggle">
<i class="fas fa-moon"></i>
</button>
<button class="btn-menu-toggle">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<!-- 主内容区 -->
<main>
<!-- 英雄区域 -->
<section id="home" class="hero">
<div class="hero-background">
<div class="hero-gradient"></div>
<div class="hero-pattern"></div>
<div class="hero-ball-animation"></div>
</div>
<div class="container">
<div class="hero-content">
<div class="hero-badge">
<span class="badge-season">2025赛季</span>
<span class="badge-league">苏超联赛第一季</span>
</div>
<h1 class="hero-title">
<span class="title-line">江苏城市</span>
<span class="title-line highlight">足球联赛</span>
</h1>
<p class="hero-subtitle">
江苏省首个城市间职业足球联赛,汇集12支精英球队,点燃2025赛季战火!
</p>
<div class="hero-stats">
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">参赛球队</div>
</div>
<div class="stat-item">
<div class="stat-number">132</div>
<div class="stat-label">场比赛</div>
</div>
<div class="stat-item">
<div class="stat-number">26</div>
<div class="stat-label">比赛周</div>
</div>
<div class="stat-item">
<div class="stat-number">1</div>
<div class="stat-label">冠军荣耀</div>
</div>
</div>
<div class="hero-actions">
<a href="#fixtures" class="btn btn-primary">
<i class="fas fa-calendar-alt"></i>
查看赛程
</a>
<a href="#standings" class="btn btn-secondary">
<i class="fas fa-trophy"></i>
积分榜
</a>
</div>
</div>
<div class="hero-visual">
<div class="stadium-visual">
<div class="stadium-field"></div>
<div class="stadium-stands"></div>
<div class="stadium-players">
<div class="player player-1"></div>
<div class="player player-2"></div>
<div class="player player-3"></div>
</div>
<div class="stadium-ball"></div>
</div>
</div>
</div>
<div class="hero-scroll">
<div class="scroll-indicator">
<div class="scroll-line"></div>
</div>
</div>
</section>
<!-- 英雄区域 -->
<section id="home" class="hero">
<div class="hero-background">
<div class="hero-gradient"></div>
<div class="hero-pattern"></div>
<div class="hero-ball-animation"></div>
</div>
<!-- 下一场比赛 -->
<section class="next-match">
<div class="container">
<div class="section-header">
<h2 class="section-title">下一场比赛</h2>
<div class="section-subtitle">即将开始的精彩对决</div>
</div>
<div class="match-card">
<div class="match-date">
<div class="match-day">周六</div>
<div class="match-date-number">25</div>
<div class="match-month">一月</div>
<div class="match-time">19:30</div>
</div>
<div class="match-teams">
<div class="team team-home">
<div class="team-logo logo-nanjing"></div>
<div class="team-name">南京城联</div>
<div class="team-record">8胜 3平 2负</div>
</div>
<div class="match-vs">
<div class="vs-text">VS</div>
<div class="match-info">
<div class="match-venue">南京奥体中心</div>
<div class="match-round">第12轮</div>
</div>
</div>
<div class="team team-away">
<div class="team-logo logo-suzhou"></div>
<div class="team-name">苏州雄狮</div>
<div class="team-record">7胜 4平 2负</div>
</div>
</div>
<div class="match-actions">
<button class="btn btn-outline">
<i class="fas fa-bell"></i>
设置提醒
</button>
<button class="btn btn-primary">
<i class="fas fa-ticket-alt"></i>
购票
</button>
</div>
</div>
<div class="container">
<div class="hero-content">
<div class="hero-badge">
<span class="badge-season">2025赛季</span>
<span class="badge-league">苏超联赛第一季</span>
</div>
</section>
<!-- 球队展示 -->
<section id="teams" class="teams-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">参赛球队</h2>
<div class="section-subtitle">12支城市代表队的荣耀之战</div>
</div>
<div class="teams-grid">
<!-- 球队卡片将通过JS动态生成 -->
</div>
</div>
</section>
<h1 class="hero-title">
<span class="title-line">江苏城市</span>
<span class="title-line highlight">足球联赛</span>
</h1>
<!-- 积分榜 -->
<section id="standings" class="standings-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">积分榜</h2>
<div class="section-subtitle">2025赛季实时排名</div>
</div>
<div class="standings-container">
<div class="standings-table">
<table>
<thead>
<tr>
<th>排名</th>
<th>球队</th>
<th>场次</th>
<th></th>
<th></th>
<th></th>
<th>进球</th>
<th>失球</th>
<th>净胜球</th>
<th>积分</th>
</tr>
</thead>
<tbody>
<!-- 积分榜数据将通过JS动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
</section>
<p class="hero-subtitle">
江苏省首个城市间职业足球联赛,汇集12支精英球队,点燃2025赛季战火!
</p>
<!-- 赛程表 -->
<section id="fixtures" class="fixtures-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">赛程表</h2>
<div class="section-subtitle">2025赛季完整赛程</div>
</div>
<div class="fixtures-tabs">
<div class="tabs">
<button class="tab active" data-round="all">全部赛程</button>
<button class="tab" data-round="next">即将比赛</button>
<button class="tab" data-round="recent">最近赛果</button>
</div>
<div class="fixtures-list">
<!-- 赛程数据将通过JS动态生成 -->
</div>
</div>
<div class="hero-stats">
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">参赛球队</div>
</div>
<div class="stat-item">
<div class="stat-number">132</div>
<div class="stat-label">场比赛</div>
</div>
<div class="stat-item">
<div class="stat-number">26</div>
<div class="stat-label">比赛</div>
</div>
<div class="stat-item">
<div class="stat-number">1</div>
<div class="stat-label">冠军荣耀</div>
</div>
</div>
</section>
<!-- 数据统计 -->
<section id="stats" class="stats-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">数据统计</h2>
<div class="section-subtitle">球员与球队数据排行榜</div>
</div>
<div class="stats-tabs">
<div class="stats-tab-nav">
<button class="stats-tab active" data-tab="scorers">射手榜</button>
<button class="stats-tab" data-tab="assists">助攻榜</button>
<button class="stats-tab" data-tab="teams">球队数据</button>
</div>
<div class="stats-content">
<div class="stats-tab-content active" id="scorers">
<!-- 射手榜数据 -->
</div>
<div class="stats-tab-content" id="assists">
<!-- 助攻榜数据 -->
</div>
<div class="stats-tab-content" id="teams">
<!-- 球队数据 -->
</div>
</div>
</div>
<div class="hero-actions">
<a href="#fixtures" class="btn btn-primary">
<i class="fas fa-calendar-alt"></i>
查看赛程
</a>
<a href="#standings" class="btn btn-secondary">
<i class="fas fa-trophy"></i>
积分榜
</a>
</div>
</section>
</div>
<!-- 新闻动态 -->
<section id="news" class="news-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">新闻动态</h2>
<div class="section-subtitle">联赛最新资讯</div>
</div>
<div class="news-grid">
<!-- 新闻卡片将通过JS动态生成 -->
</div>
<div class="hero-visual">
<div class="stadium-visual">
<div class="stadium-field"></div>
<div class="stadium-stands"></div>
<div class="stadium-players">
<div class="player player-1"></div>
<div class="player player-2"></div>
<div class="player player-3"></div>
</div>
<div class="stadium-ball"></div>
</div>
</section>
</div>
</div>
<!-- 底部 -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-brand">
<div class="logo">
<div class="logo-ball"></div>
<span class="logo-text">苏超联赛</span>
</div>
<div class="footer-description">
江苏城市足球联赛2025赛季官方网站
</div>
<div class="footer-social">
<a href="#" class="social-link"><i class="fab fa-weibo"></i></a>
<a href="#" class="social-link"><i class="fab fa-weixin"></i></a>
<a href="#" class="social-link"><i class="fab fa-douyin"></i></a>
<a href="#" class="social-link"><i class="fab fa-bilibili"></i></a>
</div>
</div>
<div class="footer-links">
<div class="footer-column">
<h3 class="footer-title">联赛信息</h3>
<a href="#" class="footer-link">关于联赛</a>
<a href="#" class="footer-link">联赛章程</a>
<a href="#" class="footer-link">组织机构</a>
<a href="#" class="footer-link">合作伙伴</a>
</div>
<div class="footer-column">
<h3 class="footer-title">球迷服务</h3>
<a href="#" class="footer-link">票务信息</a>
<a href="#" class="footer-link">球迷社区</a>
<a href="#" class="footer-link">官方商店</a>
<a href="#" class="footer-link">联系我们</a>
</div>
<div class="footer-column">
<h3 class="footer-title">媒体中心</h3>
<a href="#" class="footer-link">新闻发布</a>
<a href="#" class="footer-link">媒体资料</a>
<a href="#" class="footer-link">采访申请</a>
<a href="#" class="footer-link">摄影图库</a>
</div>
</div>
</div>
<div class="footer-bottom">
<div class="copyright">
&copy; 2025 江苏城市足球联赛. 保留所有权利.
</div>
<div class="footer-legal">
<a href="#" class="legal-link">隐私政策</a>
<a href="#" class="legal-link">使用条款</a>
<a href="#" class="legal-link">Cookie政策</a>
</div>
</div>
<div class="hero-scroll">
<div class="scroll-indicator">
<div class="scroll-line"></div>
</div>
</div>
</section>
<!-- 下一场比赛 -->
<section class="next-match">
<div class="container">
<div class="section-header">
<h2 class="section-title">下一场比赛</h2>
<div class="section-subtitle">即将开始的精彩对决</div>
</div>
<div class="match-card">
<div class="match-date">
<div class="match-day">周六</div>
<div class="match-date-number">25</div>
<div class="match-month">一月</div>
<div class="match-time">19:30</div>
</div>
</footer>
<div class="match-teams">
<div class="team team-home">
<div class="team-logo logo-nanjing"></div>
<div class="team-name">南京城联</div>
<div class="team-record">8胜 3平 2负</div>
</div>
<div class="match-vs">
<div class="vs-text">VS</div>
<div class="match-info">
<div class="match-venue">南京奥体中心</div>
<div class="match-round">第12轮</div>
</div>
</div>
<div class="team team-away">
<div class="team-logo logo-suzhou"></div>
<div class="team-name">苏州雄狮</div>
<div class="team-record">7胜 4平 2负</div>
</div>
</div>
<div class="match-actions">
<button class="btn btn-outline">
<i class="fas fa-bell"></i>
设置提醒
</button>
<button class="btn btn-primary">
<i class="fas fa-ticket-alt"></i>
购票
</button>
</div>
</div>
</div>
</section>
<!-- 球队展示 -->
<section id="teams" class="teams-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">参赛球队</h2>
<div class="section-subtitle">12支城市代表队的荣耀之战</div>
</div>
<div class="teams-grid">
<!-- 球队卡片将通过JS动态生成 -->
</div>
</div>
</section>
<!-- 积分榜 -->
<section id="standings" class="standings-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">积分榜</h2>
<div class="section-subtitle">2025赛季实时排名</div>
</div>
<div class="standings-container">
<div class="standings-table">
<table>
<thead>
<tr>
<th>排名</th>
<th>球队</th>
<th>场次</th>
<th></th>
<th></th>
<th></th>
<th>进球</th>
<th>失球</th>
<th>净胜球</th>
<th>积分</th>
</tr>
</thead>
<tbody>
<!-- 积分榜数据将通过JS动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
</section>
<!-- 赛程表 -->
<section id="fixtures" class="fixtures-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">赛程表</h2>
<div class="section-subtitle">2025赛季完整赛程</div>
</div>
<div class="fixtures-tabs">
<div class="tabs">
<button class="tab active" data-round="all">全部赛程</button>
<button class="tab" data-round="next">即将比赛</button>
<button class="tab" data-round="recent">最近赛果</button>
</div>
<div class="fixtures-list">
<!-- 赛程数据将通过JS动态生成 -->
</div>
</div>
</div>
</section>
<!-- 数据统计 -->
<section id="stats" class="stats-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">数据统计</h2>
<div class="section-subtitle">球员与球队数据排行榜</div>
</div>
<div class="stats-tabs">
<div class="stats-tab-nav">
<button class="stats-tab active" data-tab="scorers">
射手榜
</button>
<button class="stats-tab" data-tab="assists">助攻榜</button>
<button class="stats-tab" data-tab="teams">球队数据</button>
</div>
<div class="stats-content">
<div class="stats-tab-content active" id="scorers">
<!-- 射手榜数据 -->
</div>
<div class="stats-tab-content" id="assists">
<!-- 助攻榜数据 -->
</div>
<div class="stats-tab-content" id="teams">
<!-- 球队数据 -->
</div>
</div>
</div>
</div>
</section>
<!-- 新闻动态 -->
<section id="news" class="news-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">新闻动态</h2>
<div class="section-subtitle">联赛最新资讯</div>
</div>
<div class="news-grid">
<!-- 新闻卡片将通过JS动态生成 -->
</div>
</div>
</section>
<!-- 底部 -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-brand">
<div class="logo">
<div class="logo-ball"></div>
<span class="logo-text">苏超联赛</span>
</div>
<div class="footer-description">
江苏城市足球联赛2025赛季官方网站
</div>
<div class="footer-social">
<a href="#" class="social-link"><i class="fab fa-weibo"></i></a>
<a href="#" class="social-link"
><i class="fab fa-weixin"></i
></a>
<a href="#" class="social-link"
><i class="fab fa-douyin"></i
></a>
<a href="#" class="social-link"
><i class="fab fa-bilibili"></i
></a>
</div>
</div>
<div class="footer-links">
<div class="footer-column">
<h3 class="footer-title">联赛信息</h3>
<a href="#" class="footer-link">关于联赛</a>
<a href="#" class="footer-link">联赛章程</a>
<a href="#" class="footer-link">组织机构</a>
<a href="#" class="footer-link">合作伙伴</a>
</div>
<div class="footer-column">
<h3 class="footer-title">球迷服务</h3>
<a href="#" class="footer-link">票务信息</a>
<a href="#" class="footer-link">球迷社区</a>
<a href="#" class="footer-link">官方商店</a>
<a href="#" class="footer-link">联系我们</a>
</div>
<div class="footer-column">
<h3 class="footer-title">媒体中心</h3>
<a href="#" class="footer-link">新闻发布</a>
<a href="#" class="footer-link">媒体资料</a>
<a href="#" class="footer-link">采访申请</a>
<a href="#" class="footer-link">摄影图库</a>
</div>
</div>
</div>
<div class="footer-bottom">
<div class="copyright">
&copy; 2025 江苏城市足球联赛. 保留所有权利.
</div>
<div class="footer-legal">
<a href="#" class="legal-link">隐私政策</a>
<a href="#" class="legal-link">使用条款</a>
<a href="#" class="legal-link">Cookie政策</a>
</div>
</div>
</div>
</footer>
</main>
<!-- JavaScript文件 -->
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
<script src="js/data.js"></script>
<script src="js/main.js"></script>
</body>
</html>
</body>
</html>
@@ -1,163 +1,163 @@
// 江苏城市足球联赛2025赛季 - 主JavaScript文件
document.addEventListener('DOMContentLoaded', function() {
// 初始化加载动画
initLoader();
// 初始化主题切换
initThemeToggle();
// 初始化导航菜单
initNavigation();
// 初始化滚动监听
initScrollSpy();
// 渲染球队卡片
renderTeams();
// 渲染积分榜
renderStandings();
// 渲染赛程表
renderFixtures();
// 渲染数据统计
renderStats();
// 渲染新闻动态
renderNews();
// 初始化标签页切换
initTabs();
// 初始化移动端菜单
initMobileMenu();
document.addEventListener("DOMContentLoaded", function () {
// 初始化加载动画
initLoader();
// 初始化主题切换
initThemeToggle();
// 初始化导航菜单
initNavigation();
// 初始化滚动监听
initScrollSpy();
// 渲染球队卡片
renderTeams();
// 渲染积分榜
renderStandings();
// 渲染赛程表
renderFixtures();
// 渲染数据统计
renderStats();
// 渲染新闻动态
renderNews();
// 初始化标签页切换
initTabs();
// 初始化移动端菜单
initMobileMenu();
});
// 加载动画
function initLoader() {
const loader = document.querySelector('.loader');
// 模拟加载延迟
const loader = document.querySelector(".loader");
// 模拟加载延迟
setTimeout(() => {
loader.classList.add("loaded");
// 动画结束后隐藏loader
setTimeout(() => {
loader.classList.add('loaded');
// 动画结束后隐藏loader
setTimeout(() => {
loader.style.display = 'none';
}, 300);
}, 1500);
loader.style.display = "none";
}, 300);
}, 1500);
}
// 主题切换
function initThemeToggle() {
const themeToggle = document.querySelector('.btn-theme-toggle');
const themeIcon = themeToggle.querySelector('i');
// 检查本地存储的主题偏好
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);
updateThemeIcon(savedTheme);
themeToggle.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
updateThemeIcon(newTheme);
// 添加切换动画
themeToggle.style.transform = 'scale(0.9)';
setTimeout(() => {
themeToggle.style.transform = '';
}, 150);
});
function updateThemeIcon(theme) {
if (theme === 'dark') {
themeIcon.className = 'fas fa-sun';
} else {
themeIcon.className = 'fas fa-moon';
}
const themeToggle = document.querySelector(".btn-theme-toggle");
const themeIcon = themeToggle.querySelector("i");
// 检查本地存储的主题偏好
const savedTheme = localStorage.getItem("theme") || "light";
document.documentElement.setAttribute("data-theme", savedTheme);
updateThemeIcon(savedTheme);
themeToggle.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "light" ? "dark" : "light";
document.documentElement.setAttribute("data-theme", newTheme);
localStorage.setItem("theme", newTheme);
updateThemeIcon(newTheme);
// 添加切换动画
themeToggle.style.transform = "scale(0.9)";
setTimeout(() => {
themeToggle.style.transform = "";
}, 150);
});
function updateThemeIcon(theme) {
if (theme === "dark") {
themeIcon.className = "fas fa-sun";
} else {
themeIcon.className = "fas fa-moon";
}
}
}
// 导航菜单
function initNavigation() {
const navLinks = document.querySelectorAll('.nav-link');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetSection = document.querySelector(targetId);
if (targetSection) {
// 更新活动链接
navLinks.forEach(l => l.classList.remove('active'));
this.classList.add('active');
// 平滑滚动到目标区域
window.scrollTo({
top: targetSection.offsetTop - 80,
behavior: 'smooth'
});
// 如果是移动端,关闭菜单
const navMenu = document.querySelector('.nav-menu');
if (navMenu.classList.contains('active')) {
navMenu.classList.remove('active');
}
}
const navLinks = document.querySelectorAll(".nav-link");
navLinks.forEach((link) => {
link.addEventListener("click", function (e) {
e.preventDefault();
const targetId = this.getAttribute("href");
const targetSection = document.querySelector(targetId);
if (targetSection) {
// 更新活动链接
navLinks.forEach((l) => l.classList.remove("active"));
this.classList.add("active");
// 平滑滚动到目标区域
window.scrollTo({
top: targetSection.offsetTop - 80,
behavior: "smooth",
});
// 如果是移动端,关闭菜单
const navMenu = document.querySelector(".nav-menu");
if (navMenu.classList.contains("active")) {
navMenu.classList.remove("active");
}
}
});
});
}
// 滚动监听
function initScrollSpy() {
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav-link');
window.addEventListener('scroll', () => {
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.clientHeight;
if (scrollY >= sectionTop - 100) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${current}`) {
link.classList.add('active');
}
});
const sections = document.querySelectorAll("section[id]");
const navLinks = document.querySelectorAll(".nav-link");
window.addEventListener("scroll", () => {
let current = "";
sections.forEach((section) => {
const sectionTop = section.offsetTop;
const sectionHeight = section.clientHeight;
if (scrollY >= sectionTop - 100) {
current = section.getAttribute("id");
}
});
navLinks.forEach((link) => {
link.classList.remove("active");
if (link.getAttribute("href") === `#${current}`) {
link.classList.add("active");
}
});
});
}
// 渲染球队卡片
function renderTeams() {
const teamsGrid = document.querySelector('.teams-grid');
if (!teamsGrid) return;
teamsGrid.innerHTML = '';
leagueData.teams.forEach(team => {
const teamCard = document.createElement('div');
teamCard.className = 'team-card';
// 获取球队统计数据
const standing = leagueData.standings.find(s => s.teamId === team.id);
teamCard.innerHTML = `
const teamsGrid = document.querySelector(".teams-grid");
if (!teamsGrid) return;
teamsGrid.innerHTML = "";
leagueData.teams.forEach((team) => {
const teamCard = document.createElement("div");
teamCard.className = "team-card";
// 获取球队统计数据
const standing = leagueData.standings.find((s) => s.teamId === team.id);
teamCard.innerHTML = `
<div class="team-card-logo" style="background: linear-gradient(135deg, ${team.colors[0]} 0%, ${team.colors[1]} 100%);">
${team.shortName}
</div>
@@ -165,52 +165,52 @@ function renderTeams() {
<div class="team-card-city">${team.city}</div>
<div class="team-card-stats">
<div class="team-stat">
<div class="team-stat-value">${standing ? standing.rank : '-'}</div>
<div class="team-stat-value">${standing ? standing.rank : "-"}</div>
<div class="team-stat-label">排名</div>
</div>
<div class="team-stat">
<div class="team-stat-value">${standing ? standing.points : '0'}</div>
<div class="team-stat-value">${standing ? standing.points : "0"}</div>
<div class="team-stat-label">积分</div>
</div>
<div class="team-stat">
<div class="team-stat-value">${standing ? standing.goalDifference : '0'}</div>
<div class="team-stat-value">${standing ? standing.goalDifference : "0"}</div>
<div class="team-stat-label">净胜球</div>
</div>
</div>
`;
teamCard.addEventListener('click', () => {
// 这里可以添加点击跳转到球队详情页的功能
alert(`查看 ${team.name} 的详细信息`);
});
teamsGrid.appendChild(teamCard);
teamCard.addEventListener("click", () => {
// 这里可以添加点击跳转到球队详情页的功能
alert(`查看 ${team.name} 的详细信息`);
});
teamsGrid.appendChild(teamCard);
});
}
// 渲染积分榜
function renderStandings() {
const standingsTable = document.querySelector('.standings-table tbody');
if (!standingsTable) return;
standingsTable.innerHTML = '';
leagueData.standings.forEach(standing => {
const team = getTeamById(standing.teamId);
const row = document.createElement('tr');
// 根据排名添加特殊样式
if (standing.rank <= 4) {
row.classList.add('champions-league');
} else if (standing.rank <= 6) {
row.classList.add('europa-league');
} else if (standing.rank >= 11) {
row.classList.add('relegation');
}
row.innerHTML = `
const standingsTable = document.querySelector(".standings-table tbody");
if (!standingsTable) return;
standingsTable.innerHTML = "";
leagueData.standings.forEach((standing) => {
const team = getTeamById(standing.teamId);
const row = document.createElement("tr");
// 根据排名添加特殊样式
if (standing.rank <= 4) {
row.classList.add("champions-league");
} else if (standing.rank <= 6) {
row.classList.add("europa-league");
} else if (standing.rank >= 11) {
row.classList.add("relegation");
}
row.innerHTML = `
<td>${standing.rank}</td>
<td>
<div style="display: flex; align-items: center; gap: 0.5rem;">
@@ -224,70 +224,80 @@ function renderStandings() {
<td>${standing.lost}</td>
<td>${standing.goalsFor}</td>
<td>${standing.goalsAgainst}</td>
<td>${standing.goalDifference > 0 ? '+' : ''}${standing.goalDifference}</td>
<td>${standing.goalDifference > 0 ? "+" : ""}${standing.goalDifference}</td>
<td><strong>${standing.points}</strong></td>
`;
standingsTable.appendChild(row);
});
standingsTable.appendChild(row);
});
}
// 渲染赛程表
function renderFixtures() {
const fixturesList = document.querySelector('.fixtures-list');
if (!fixturesList) return;
fixturesList.innerHTML = '';
// 按轮次分组
const fixturesByRound = {};
leagueData.fixtures.forEach(fixture => {
if (!fixturesByRound[fixture.round]) {
fixturesByRound[fixture.round] = [];
}
fixturesByRound[fixture.round].push(fixture);
});
// 渲染所有赛程
Object.keys(fixturesByRound).sort((a, b) => a - b).forEach(round => {
const roundHeader = document.createElement('div');
roundHeader.className = 'fixture-round-header';
roundHeader.innerHTML = `<h3>第${round}轮</h3>`;
fixturesList.appendChild(roundHeader);
fixturesByRound[round].forEach(fixture => {
const homeTeam = getTeamById(fixture.homeTeamId);
const awayTeam = getTeamById(fixture.awayTeamId);
const fixtureItem = document.createElement('div');
fixtureItem.className = 'fixture-item';
const date = new Date(fixture.date);
const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const dayName = dayNames[date.getDay()];
let scoreHtml = '';
let statusText = '';
if (fixture.status === 'completed') {
scoreHtml = `
const fixturesList = document.querySelector(".fixtures-list");
if (!fixturesList) return;
fixturesList.innerHTML = "";
// 按轮次分组
const fixturesByRound = {};
leagueData.fixtures.forEach((fixture) => {
if (!fixturesByRound[fixture.round]) {
fixturesByRound[fixture.round] = [];
}
fixturesByRound[fixture.round].push(fixture);
});
// 渲染所有赛程
Object.keys(fixturesByRound)
.sort((a, b) => a - b)
.forEach((round) => {
const roundHeader = document.createElement("div");
roundHeader.className = "fixture-round-header";
roundHeader.innerHTML = `<h3>第${round}轮</h3>`;
fixturesList.appendChild(roundHeader);
fixturesByRound[round].forEach((fixture) => {
const homeTeam = getTeamById(fixture.homeTeamId);
const awayTeam = getTeamById(fixture.awayTeamId);
const fixtureItem = document.createElement("div");
fixtureItem.className = "fixture-item";
const date = new Date(fixture.date);
const dayNames = [
"周日",
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
];
const dayName = dayNames[date.getDay()];
let scoreHtml = "";
let statusText = "";
if (fixture.status === "completed") {
scoreHtml = `
<div class="fixture-score-value">${fixture.homeScore} - ${fixture.awayScore}</div>
<div class="fixture-score-status">已结束</div>
`;
} else if (fixture.status === 'scheduled') {
scoreHtml = `
} else if (fixture.status === "scheduled") {
scoreHtml = `
<div class="fixture-score-value">VS</div>
<div class="fixture-score-status">${fixture.time}</div>
`;
} else {
scoreHtml = `
} else {
scoreHtml = `
<div class="fixture-score-value">-</div>
<div class="fixture-score-status">待定</div>
`;
}
fixtureItem.innerHTML = `
}
fixtureItem.innerHTML = `
<div class="fixture-date">
<div class="fixture-day">${dayName}</div>
<div class="fixture-time">${formatDate(fixture.date)}</div>
@@ -307,25 +317,25 @@ function renderFixtures() {
${scoreHtml}
</div>
`;
fixturesList.appendChild(fixtureItem);
});
fixturesList.appendChild(fixtureItem);
});
});
}
// 渲染数据统计
function renderStats() {
renderScorers();
renderAssists();
renderTeamStats();
renderScorers();
renderAssists();
renderTeamStats();
}
function renderScorers() {
const scorersContainer = document.querySelector('#scorers');
if (!scorersContainer) return;
scorersContainer.innerHTML = `
const scorersContainer = document.querySelector("#scorers");
if (!scorersContainer) return;
scorersContainer.innerHTML = `
<table class="stats-table">
<thead>
<tr>
@@ -338,7 +348,8 @@ function renderScorers() {
</tr>
</thead>
<tbody>
${leagueData.players.scorers.map(player => {
${leagueData.players.scorers
.map((player) => {
const team = getTeamById(player.teamId);
return `
<tr>
@@ -350,18 +361,19 @@ function renderScorers() {
<td class="stats-value">${player.matches}</td>
</tr>
`;
}).join('')}
})
.join("")}
</tbody>
</table>
`;
}
function renderAssists() {
const assistsContainer = document.querySelector('#assists');
if (!assistsContainer) return;
assistsContainer.innerHTML = `
const assistsContainer = document.querySelector("#assists");
if (!assistsContainer) return;
assistsContainer.innerHTML = `
<table class="stats-table">
<thead>
<tr>
@@ -374,7 +386,8 @@ function renderAssists() {
</tr>
</thead>
<tbody>
${leagueData.players.assists.map(player => {
${leagueData.players.assists
.map((player) => {
const team = getTeamById(player.teamId);
return `
<tr>
@@ -386,36 +399,41 @@ function renderAssists() {
<td class="stats-value">${player.matches}</td>
</tr>
`;
}).join('')}
})
.join("")}
</tbody>
</table>
`;
}
function renderTeamStats() {
const teamStatsContainer = document.querySelector('#teams');
if (!teamStatsContainer) return;
// 计算球队统计数据
const teamStats = leagueData.standings.map(standing => {
const team = getTeamById(standing.teamId);
const goalsPerGame = (standing.goalsFor / standing.played).toFixed(2);
const concededPerGame = (standing.goalsAgainst / standing.played).toFixed(2);
return {
rank: standing.rank,
team: team.name,
goalsFor: standing.goalsFor,
goalsAgainst: standing.goalsAgainst,
goalDifference: standing.goalDifference,
goalsPerGame,
concededPerGame,
cleanSheets: Math.floor(Math.random() * 5) // 模拟数据
};
}).sort((a, b) => a.rank - b.rank);
teamStatsContainer.innerHTML = `
const teamStatsContainer = document.querySelector("#teams");
if (!teamStatsContainer) return;
// 计算球队统计数据
const teamStats = leagueData.standings
.map((standing) => {
const team = getTeamById(standing.teamId);
const goalsPerGame = (standing.goalsFor / standing.played).toFixed(2);
const concededPerGame = (standing.goalsAgainst / standing.played).toFixed(
2,
);
return {
rank: standing.rank,
team: team.name,
goalsFor: standing.goalsFor,
goalsAgainst: standing.goalsAgainst,
goalDifference: standing.goalDifference,
goalsPerGame,
concededPerGame,
cleanSheets: Math.floor(Math.random() * 5), // 模拟数据
};
})
.sort((a, b) => a.rank - b.rank);
teamStatsContainer.innerHTML = `
<table class="stats-table">
<thead>
<tr>
@@ -430,18 +448,22 @@ function renderTeamStats() {
</tr>
</thead>
<tbody>
${teamStats.map(stat => `
${teamStats
.map(
(stat) => `
<tr>
<td class="stats-rank">${stat.rank}</td>
<td class="stats-player">${stat.team}</td>
<td class="stats-value">${stat.goalsFor}</td>
<td class="stats-value">${stat.goalsAgainst}</td>
<td class="stats-value">${stat.goalDifference > 0 ? '+' : ''}${stat.goalDifference}</td>
<td class="stats-value">${stat.goalDifference > 0 ? "+" : ""}${stat.goalDifference}</td>
<td class="stats-value">${stat.goalsPerGame}</td>
<td class="stats-value">${stat.concededPerGame}</td>
<td class="stats-value">${stat.cleanSheets}</td>
</tr>
`).join('')}
`,
)
.join("")}
</tbody>
</table>
`;
@@ -449,24 +471,24 @@ function renderTeamStats() {
// 渲染新闻动态
function renderNews() {
const newsGrid = document.querySelector('.news-grid');
if (!newsGrid) return;
newsGrid.innerHTML = '';
leagueData.news.forEach(newsItem => {
const newsCard = document.createElement('div');
newsCard.className = 'news-card';
const date = new Date(newsItem.date);
const formattedDate = date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
newsCard.innerHTML = `
const newsGrid = document.querySelector(".news-grid");
if (!newsGrid) return;
newsGrid.innerHTML = "";
leagueData.news.forEach((newsItem) => {
const newsCard = document.createElement("div");
newsCard.className = "news-card";
const date = new Date(newsItem.date);
const formattedDate = date.toLocaleDateString("zh-CN", {
year: "numeric",
month: "long",
day: "numeric",
});
newsCard.innerHTML = `
<div class="news-card-image" style="background: linear-gradient(135deg, ${newsItem.imageColor} 0%, ${darkenColor(newsItem.imageColor, 20)} 100%);"></div>
<div class="news-card-content">
<span class="news-card-category">${newsItem.category}</span>
@@ -481,138 +503,143 @@ function renderNews() {
</div>
</div>
`;
newsCard.addEventListener('click', () => {
alert(`查看新闻: ${newsItem.title}`);
});
newsGrid.appendChild(newsCard);
newsCard.addEventListener("click", () => {
alert(`查看新闻: ${newsItem.title}`);
});
newsGrid.appendChild(newsCard);
});
}
// 初始化标签页切换
function initTabs() {
// 赛程标签页
const fixtureTabs = document.querySelectorAll('.fixtures-tabs .tab');
const fixtureItems = document.querySelectorAll('.fixture-item');
fixtureTabs.forEach(tab => {
tab.addEventListener('click', () => {
// 更新活动标签
fixtureTabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
const roundFilter = tab.getAttribute('data-round');
// 这里可以根据筛选条件显示不同的赛程
// 由于时间关系,这里只是简单的演示
console.log(`筛选赛程: ${roundFilter}`);
});
// 赛程标签页
const fixtureTabs = document.querySelectorAll(".fixtures-tabs .tab");
const fixtureItems = document.querySelectorAll(".fixture-item");
fixtureTabs.forEach((tab) => {
tab.addEventListener("click", () => {
// 更新活动标签
fixtureTabs.forEach((t) => t.classList.remove("active"));
tab.classList.add("active");
const roundFilter = tab.getAttribute("data-round");
// 这里可以根据筛选条件显示不同的赛程
// 由于时间关系,这里只是简单的演示
console.log(`筛选赛程: ${roundFilter}`);
});
// 数据统计标签页
const statsTabs = document.querySelectorAll('.stats-tab');
const statsContents = document.querySelectorAll('.stats-tab-content');
statsTabs.forEach(tab => {
tab.addEventListener('click', () => {
const tabId = tab.getAttribute('data-tab');
// 更新活动标签
statsTabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
// 显示对应内容
statsContents.forEach(content => {
content.classList.remove('active');
if (content.id === tabId) {
content.classList.add('active');
}
});
});
});
// 数据统计标签页
const statsTabs = document.querySelectorAll(".stats-tab");
const statsContents = document.querySelectorAll(".stats-tab-content");
statsTabs.forEach((tab) => {
tab.addEventListener("click", () => {
const tabId = tab.getAttribute("data-tab");
// 更新活动标签
statsTabs.forEach((t) => t.classList.remove("active"));
tab.classList.add("active");
// 显示对应内容
statsContents.forEach((content) => {
content.classList.remove("active");
if (content.id === tabId) {
content.classList.add("active");
}
});
});
});
}
// 初始化移动端菜单
function initMobileMenu() {
const menuToggle = document.querySelector('.btn-menu-toggle');
const navMenu = document.querySelector('.nav-menu');
if (menuToggle && navMenu) {
menuToggle.addEventListener('click', () => {
navMenu.classList.toggle('active');
// 更新菜单图标
const icon = menuToggle.querySelector('i');
if (navMenu.classList.contains('active')) {
icon.className = 'fas fa-times';
} else {
icon.className = 'fas fa-bars';
}
});
// 点击菜单外区域关闭菜单
document.addEventListener('click', (e) => {
if (!navMenu.contains(e.target) && !menuToggle.contains(e.target)) {
navMenu.classList.remove('active');
menuToggle.querySelector('i').className = 'fas fa-bars';
}
});
}
const menuToggle = document.querySelector(".btn-menu-toggle");
const navMenu = document.querySelector(".nav-menu");
if (menuToggle && navMenu) {
menuToggle.addEventListener("click", () => {
navMenu.classList.toggle("active");
// 更新菜单图标
const icon = menuToggle.querySelector("i");
if (navMenu.classList.contains("active")) {
icon.className = "fas fa-times";
} else {
icon.className = "fas fa-bars";
}
});
// 点击菜单外区域关闭菜单
document.addEventListener("click", (e) => {
if (!navMenu.contains(e.target) && !menuToggle.contains(e.target)) {
navMenu.classList.remove("active");
menuToggle.querySelector("i").className = "fas fa-bars";
}
});
}
}
// 工具函数:加深颜色
function darkenColor(color, percent) {
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) - amt;
const G = (num >> 8 & 0x00FF) - amt;
const B = (num & 0x0000FF) - amt;
return "#" + (
0x1000000 +
(R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
(G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
(B < 255 ? B < 1 ? 0 : B : 255)
).toString(16).slice(1);
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) - amt;
const G = ((num >> 8) & 0x00ff) - amt;
const B = (num & 0x0000ff) - amt;
return (
"#" +
(
0x1000000 +
(R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +
(G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +
(B < 255 ? (B < 1 ? 0 : B) : 255)
)
.toString(16)
.slice(1)
);
}
// 工具函数:格式化日期(简写)
function formatDate(dateString) {
const date = new Date(dateString);
const month = date.getMonth() + 1;
const day = date.getDate();
return `${month}${day}`;
const date = new Date(dateString);
const month = date.getMonth() + 1;
const day = date.getDate();
return `${month}${day}`;
}
// 工具函数:根据ID获取球队信息
function getTeamById(teamId) {
return leagueData.teams.find(team => team.id === teamId);
return leagueData.teams.find((team) => team.id === teamId);
}
// 添加一些交互效果
document.addEventListener('DOMContentLoaded', () => {
// 为所有按钮添加点击效果
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('mousedown', () => {
button.style.transform = 'scale(0.95)';
});
button.addEventListener('mouseup', () => {
button.style.transform = '';
});
button.addEventListener('mouseleave', () => {
button.style.transform = '';
});
document.addEventListener("DOMContentLoaded", () => {
// 为所有按钮添加点击效果
const buttons = document.querySelectorAll(".btn");
buttons.forEach((button) => {
button.addEventListener("mousedown", () => {
button.style.transform = "scale(0.95)";
});
// 为卡片添加悬停效果
const cards = document.querySelectorAll('.team-card, .news-card');
cards.forEach(card => {
card.addEventListener('mouseenter', () => {
card.style.transition = 'transform 0.3s ease, box-shadow 0.3s ease';
});
button.addEventListener("mouseup", () => {
button.style.transform = "";
});
});
button.addEventListener("mouseleave", () => {
button.style.transform = "";
});
});
// 为卡片添加悬停效果
const cards = document.querySelectorAll(".team-card, .news-card");
cards.forEach((card) => {
card.addEventListener("mouseenter", () => {
card.style.transition = "transform 0.3s ease, box-shadow 0.3s ease";
});
});
});