计协官网

This commit is contained in:
skxjx2024. 2025-05-03 23:18:01 +08:00
parent e5909159fb
commit 28d607ec9f

View File

@ -132,6 +132,11 @@
color: var(--secondary-color); color: var(--secondary-color);
} }
.logo img {
width: auto;
height: 50px;
}
/* 汉堡菜单按钮 */ /* 汉堡菜单按钮 */
.hamburger { .hamburger {
display: none; display: none;
@ -162,7 +167,8 @@
top: 0; top: 0;
} }
.hamburger span:nth-child(2), .hamburger span:nth-child(3) { .hamburger span:nth-child(2),
.hamburger span:nth-child(3) {
top: 9px; top: 9px;
} }
@ -229,11 +235,11 @@
border-radius: 50%; border-radius: 50%;
} }
input:checked + .slider { input:checked+.slider {
background-color: var(--secondary-color); background-color: var(--secondary-color);
} }
input:checked + .slider:before { input:checked+.slider:before {
transform: translateX(30px); transform: translateX(30px);
} }
@ -475,17 +481,17 @@
color: var(--secondary-color); color: var(--secondary-color);
font-size: 18px; font-size: 18px;
} }
.loading-spinner i { .loading-spinner i {
margin-right: 10px; margin-right: 10px;
} }
.news-card img { .news-card img {
width: 100%; width: 100%;
height: 200px; height: 200px;
object-fit: cover; object-fit: cover;
} }
.error-message { .error-message {
color: #ff6b6b; color: #ff6b6b;
text-align: center; text-align: center;
@ -498,11 +504,11 @@
.hero-title { .hero-title {
font-size: 48px; font-size: 48px;
} }
.nav-links { .nav-links {
display: none; display: none;
} }
.hamburger { .hamburger {
display: block; display: block;
} }
@ -512,23 +518,23 @@
.hero-title { .hero-title {
font-size: 36px; font-size: 36px;
} }
.hero-description { .hero-description {
font-size: 16px; font-size: 16px;
} }
.section-title { .section-title {
font-size: 28px; font-size: 28px;
} }
.links-grid { .links-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.footer-links { .footer-links {
flex-wrap: wrap; flex-wrap: wrap;
} }
.footer-links li { .footer-links li {
margin: 10px 15px; margin: 10px 15px;
} }
@ -538,37 +544,53 @@
.hero-title { .hero-title {
font-size: 32px; font-size: 32px;
} }
.hero-subtitle { .hero-subtitle {
font-size: 16px; font-size: 16px;
} }
.btn { .btn {
padding: 10px 20px; padding: 10px 20px;
font-size: 14px; font-size: 14px;
} }
.theme-switch { .theme-switch {
width: 50px; width: 50px;
height: 25px; height: 25px;
margin-left: 15px; margin-left: 15px;
} }
.slider:before { .slider:before {
height: 18px; height: 18px;
width: 18px; width: 18px;
bottom: 3.5px; bottom: 3.5px;
left: 3.5px; left: 3.5px;
} }
input:checked + .slider:before { input:checked+.slider:before {
transform: translateX(25px); transform: translateX(25px);
} }
.slider .icon { .slider .icon {
font-size: 12px; font-size: 12px;
} }
} }
.close-btn {
position: absolute;
top: 20px;
right: 20px;
background: none;
border: none;
color: var(--text-primary);
font-size: 24px;
cursor: pointer;
z-index: 1001;
}
.close-btn:hover {
color: var(--secondary-color);
}
</style> </style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head> </head>
@ -578,7 +600,9 @@
<header> <header>
<div class="container"> <div class="container">
<nav> <nav>
<div class="logo">石科信计算机协会</div> <div class="logo">
<img id="logoImage" src="images/skx-w.png" alt="石科信计算机协会">
</div>
<button class="hamburger" id="hamburger"> <button class="hamburger" id="hamburger">
<span></span> <span></span>
<span></span> <span></span>
@ -607,6 +631,9 @@
<!-- 移动端导航菜单 --> <!-- 移动端导航菜单 -->
<div class="mobile-nav" id="mobileNav"> <div class="mobile-nav" id="mobileNav">
<button class="close-btn" id="closeBtn">
<i class="fas fa-times"></i>
</button>
<ul class="mobile-nav-links"> <ul class="mobile-nav-links">
<li><a href="/">首页</a></li> <li><a href="/">首页</a></li>
<li><a href="/about">协会介绍</a></li> <li><a href="/about">协会介绍</a></li>
@ -694,180 +721,206 @@
</footer> </footer>
<script> <script>
// 平滑滚动 // 获取主题切换开关元素
document.querySelectorAll('a[href^="#"]').forEach(anchor => { const themeToggle = document.getElementById('themeToggle');
anchor.addEventListener('click', function (e) { const mobileThemeToggle = document.getElementById('mobileThemeToggle');
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({ // 获取 logo 图片元素
behavior: 'smooth' const logoImage = document.getElementById('logoImage');
});
}); // 根据主题模式更新 logo 图片
function updateLogoImage() {
const currentTheme = document.documentElement.getAttribute('data-theme');
if (currentTheme === 'light') {
logoImage.src = './images/skx-b.png'; // 亮色模式图片
} else {
logoImage.src = './images/skx-w.png'; // 暗色模式图片
}
}
// 初始化时设置 logo 图片
updateLogoImage();
// 平滑滚动
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
}); });
});
});
// 导航栏滚动效果 // 导航栏滚动效果
window.addEventListener('scroll', function () { window.addEventListener('scroll', function () {
const header = document.querySelector('header'); const header = document.querySelector('header');
if (window.scrollY > 50) { if (window.scrollY > 50) {
header.style.boxShadow = '0 5px 20px rgba(0, 0, 0, 0.1)'; header.style.boxShadow = '0 5px 20px rgba(0, 0, 0, 0.1)';
} else { } else {
header.style.boxShadow = 'none'; header.style.boxShadow = 'none';
} }
}); });
// 汉堡菜单功能 // 汉堡菜单功能
const hamburger = document.getElementById('hamburger'); const hamburger = document.getElementById('hamburger');
const mobileNav = document.getElementById('mobileNav'); const mobileNav = document.getElementById('mobileNav');
hamburger.addEventListener('click', function() {
this.classList.toggle('open');
mobileNav.classList.toggle('open');
// 切换body的overflow以防止页面滚动
if (mobileNav.classList.contains('open')) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
});
// 关闭移动菜单当点击菜单项
document.querySelectorAll('.mobile-nav-links a').forEach(link => {
link.addEventListener('click', function() {
hamburger.classList.remove('open');
mobileNav.classList.remove('open');
document.body.style.overflow = '';
});
});
// 主题切换功能 hamburger.addEventListener('click', function () {
const themeToggle = document.getElementById('themeToggle'); this.classList.toggle('open');
const mobileThemeToggle = document.getElementById('mobileThemeToggle'); mobileNav.classList.toggle('open');
// 检查本地存储中的主题偏好 // 切换body的overflow以防止页面滚动
const currentTheme = localStorage.getItem('theme') || 'dark'; if (mobileNav.classList.contains('open')) {
document.documentElement.setAttribute('data-theme', currentTheme); document.body.style.overflow = 'hidden';
updateThemeToggle(currentTheme); } else {
document.body.style.overflow = '';
}
});
// 切换主题 // 关闭移动菜单当点击菜单项
function toggleTheme() { document.querySelectorAll('.mobile-nav-links a').forEach(link => {
const currentTheme = document.documentElement.getAttribute('data-theme'); link.addEventListener('click', function () {
const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; hamburger.classList.remove('open');
mobileNav.classList.remove('open');
document.body.style.overflow = '';
});
});
document.documentElement.setAttribute('data-theme', newTheme); const closeBtn = document.getElementById('closeBtn');
localStorage.setItem('theme', newTheme);
updateThemeToggle(newTheme); closeBtn.addEventListener('click', function () {
hamburger.classList.remove('open');
mobileNav.classList.remove('open');
document.body.style.overflow = '';
});
// 检查本地存储中的主题偏好
const currentTheme = localStorage.getItem('theme') || 'dark';
document.documentElement.setAttribute('data-theme', currentTheme);
updateThemeToggle(currentTheme);
updateLogoImage(); // 初始化时也更新logo图片
// 切换主题
function toggleTheme() {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
updateThemeToggle(newTheme);
updateLogoImage(); // 主题切换时更新logo图片
}
// 更新主题切换状态
function updateThemeToggle(theme) {
const isLight = theme === 'light';
themeToggle.checked = isLight;
mobileThemeToggle.checked = isLight;
}
// 添加事件监听器
themeToggle.addEventListener('change', toggleTheme);
mobileThemeToggle.addEventListener('change', toggleTheme);
// 获取最新文章的函数
async function fetchLatestNews() {
const newsContainer = document.getElementById('newsContainer');
try {
// 构造API请求URL
const apiUrl = new URL('https://news.skxjx.holytreasure.space/');
apiUrl.searchParams.append('rest-api', 'article_list');
apiUrl.searchParams.append('count', '3'); // 获取3篇文章
apiUrl.searchParams.append('sort_id', '2'); // 分类ID为2的文章
apiUrl.searchParams.append('order', 'views'); // 按浏览量排序(可选)
const response = await fetch(apiUrl.toString());
if (!response.ok) {
throw new Error(`HTTP错误! 状态码: ${response.status}`);
} }
// 更新主题切换状态 const result = await response.json();
function updateThemeToggle(theme) {
const isLight = theme === 'light'; // 检查API返回的数据结构
themeToggle.checked = isLight; if (result.code !== 0 || !result.data || !result.data.articles) {
mobileThemeToggle.checked = isLight; throw new Error('API返回数据格式不正确');
} }
// 添加事件监听器 renderNews(result.data.articles);
themeToggle.addEventListener('change', toggleTheme); } catch (error) {
mobileThemeToggle.addEventListener('change', toggleTheme); console.error('获取最新动态失败:', error);
newsContainer.innerHTML = `
<div class="error-message">
<i class="fas fa-exclamation-triangle"></i>
<p>加载动态失败: ${error.message}</p>
<p>请稍后刷新页面重试</p>
</div>
`;
}
}
// 获取最新文章的函数 // 渲染文章列表
async function fetchLatestNews() { function renderNews(articles) {
const newsContainer = document.getElementById('newsContainer'); const newsContainer = document.getElementById('newsContainer');
newsContainer.innerHTML = '';
try {
// 构造API请求URL if (!articles || articles.length === 0) {
const apiUrl = new URL('https://news.skxjx.holytreasure.space/'); newsContainer.innerHTML = '<p class="no-news">暂无最新动态</p>';
apiUrl.searchParams.append('rest-api', 'article_list'); return;
apiUrl.searchParams.append('count', '3'); // 获取3篇文章 }
apiUrl.searchParams.append('sort_id', '2'); // 分类ID为2的文章
apiUrl.searchParams.append('order', 'views'); // 按浏览量排序(可选) articles.forEach(article => {
const newsCard = document.createElement('div');
const response = await fetch(apiUrl.toString()); newsCard.className = 'news-card';
if (!response.ok) { // 格式化日期 (从 "2021-10-11 08:04:11" 转为 "2021年10月11日")
throw new Error(`HTTP错误! 状态码: ${response.status}`); const formattedDate = formatDate(article.date);
}
// 构造文章卡片
const result = await response.json(); newsCard.innerHTML = `
<div class="news-image">
// 检查API返回的数据结构 ${article.cover ?
if (result.code !== 0 || !result.data || !result.data.articles) { `<img src="${article.cover}" alt="${article.title}" loading="lazy">` :
throw new Error('API返回数据格式不正确'); '<div class="default-image">文章图片</div>'}
} </div>
<div class="news-content">
renderNews(result.data.articles); <p class="news-date">${formattedDate}</p>
} catch (error) { <h3 class="news-title">${article.title}</h3>
console.error('获取最新动态失败:', error); <p class="news-excerpt">${article.description || '暂无摘要'}</p>
newsContainer.innerHTML = ` <div class="article-meta">
<div class="error-message"> <span><i class="far fa-eye"></i> ${article.views}</span>
<i class="fas fa-exclamation-triangle"></i> <span><i class="far fa-comment"></i> ${article.comnum}</span>
<p>加载动态失败: ${error.message}</p> ${article.sort_name ? `<span><i class="fas fa-tag"></i> ${article.sort_name}</span>` : ''}
<p>请稍后刷新页面重试</p> </div>
</div> <a href="${article.url}" class="btn" target="_blank">阅读更多</a>
`; </div>
} `;
newsContainer.appendChild(newsCard);
});
}
// 辅助函数:格式化日期
function formatDate(dateString) {
if (!dateString) return '未知日期';
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return dateString; // 如果无法解析,返回原始字符串
} }
// 渲染文章列表 return `${date.getFullYear()}年${(date.getMonth() + 1).toString().padStart(2, '0')}月${date.getDate().toString().padStart(2, '0')}日`;
function renderNews(articles) { } catch (e) {
const newsContainer = document.getElementById('newsContainer'); return dateString;
newsContainer.innerHTML = ''; }
}
if (!articles || articles.length === 0) {
newsContainer.innerHTML = '<p class="no-news">暂无最新动态</p>'; // 页面加载完成后获取最新动态
return; document.addEventListener('DOMContentLoaded', fetchLatestNews);
} </script>
articles.forEach(article => {
const newsCard = document.createElement('div');
newsCard.className = 'news-card';
// 格式化日期 (从 "2021-10-11 08:04:11" 转为 "2021年10月11日")
const formattedDate = formatDate(article.date);
// 构造文章卡片
newsCard.innerHTML = `
<div class="news-image">
${article.cover ?
`<img src="${article.cover}" alt="${article.title}" loading="lazy">` :
'<div class="default-image">文章图片</div>'}
</div>
<div class="news-content">
<p class="news-date">${formattedDate}</p>
<h3 class="news-title">${article.title}</h3>
<p class="news-excerpt">${article.description || '暂无摘要'}</p>
<div class="article-meta">
<span><i class="far fa-eye"></i> ${article.views}</span>
<span><i class="far fa-comment"></i> ${article.comnum}</span>
${article.sort_name ? `<span><i class="fas fa-tag"></i> ${article.sort_name}</span>` : ''}
</div>
<a href="${article.url}" class="btn" target="_blank">阅读更多</a>
</div>
`;
newsContainer.appendChild(newsCard);
});
}
// 辅助函数:格式化日期
function formatDate(dateString) {
if (!dateString) return '未知日期';
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return dateString; // 如果无法解析,返回原始字符串
}
return `${date.getFullYear()}年${(date.getMonth() + 1).toString().padStart(2, '0')}月${date.getDate().toString().padStart(2, '0')}日`;
} catch (e) {
return dateString;
}
}
// 页面加载完成后获取最新动态
document.addEventListener('DOMContentLoaded', fetchLatestNews);
</script>
</body> </body>
</html> </html>