feat: Refactor navbar and mobile menu into components for improved organization and maintainability

This commit is contained in:
zhangyuheng
2026-02-28 10:44:44 +08:00
parent 5772fc54c1
commit a3a972a2bc
9 changed files with 147 additions and 219 deletions

125
components.js Normal file
View File

@@ -0,0 +1,125 @@
const Components = {
navbarHTML: `
<nav class="navbar">
<div class="nav-content">
<button class="mobile-toggle" id="mobile-toggle" aria-label="菜单">
<i class="fas fa-bars"></i>
</button>
<div class="logo">
<a href="/">
<img src="https://img.lunadeer.cn/i/2024/04/22/6625ce6c8ddc1.png" alt="白鹿原 Minecraft 服务器 Logo">
</a>
</div>
<div class="nav-links desktop-only">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439" target="_blank">文档</a>
<a href="https://mcmap.lunadeer.cn/" target="_blank">地图</a>
<a href="https://mcphoto.lunadeer.cn/" target="_blank">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6" target="_blank">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html">赞助</a>
</div>
<div class="nav-cta-container">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439/doc/5yqg5ywl5pyn5yqh5zmo-WE4jkTxRmM" class="nav-cta" target="_blank">加入游戏</a>
</div>
</div>
</nav>
<!-- Mobile Menu -->
<div class="mobile-menu" id="mobile-menu">
<div class="mobile-menu-links">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439" target="_blank">文档</a>
<a href="https://mcmap.lunadeer.cn/" target="_blank">地图</a>
<a href="https://mcphoto.lunadeer.cn/" target="_blank">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6" target="_blank">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html">赞助</a>
</div>
</div>
`,
footerHTML: `
<footer>
<div class="container">
<div class="footer-content">
<div class="footer-logo">白鹿原</div>
<p>&copy; 2026 白鹿原 Minecraft 服务器.</p>
</div>
</div>
</footer>
`,
init: function() {
// Inject Navbar
const navContainer = document.getElementById('navbar-component');
if (navContainer) {
navContainer.innerHTML = this.navbarHTML;
}
// Inject Footer
const footerContainer = document.getElementById('footer-component');
if (footerContainer) {
footerContainer.innerHTML = this.footerHTML;
}
// Setup Mobile Menu Logic
this.setupMobileMenu();
// Highlight current page
this.highlightCurrentPage();
},
setupMobileMenu: function() {
const toggle = document.getElementById('mobile-toggle');
const menu = document.getElementById('mobile-menu');
if (toggle && menu) {
const icon = toggle.querySelector('i');
// Remove old listeners if any to avoid duplicates?
// Since we just injected the HTML, there are no listeners.
toggle.addEventListener('click', () => {
menu.classList.toggle('active');
document.body.classList.toggle('menu-open');
if (menu.classList.contains('active')) {
if(icon) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
}
} else {
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
}
});
menu.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
menu.classList.remove('active');
document.body.classList.remove('menu-open');
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
});
});
}
},
highlightCurrentPage: function() {
const currentPath = window.location.pathname;
const links = document.querySelectorAll('.nav-links a, .mobile-menu-links a');
links.forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active'); // You might need to add CSS for .active
}
});
}
};
document.addEventListener('DOMContentLoaded', () => {
Components.init();
});

View File

@@ -1 +1,2 @@
服务器升级M4 Mac Mini 32G,2740,5000 服务器升级M4 Mac Mini 32G,2740,5000
给服主换车,0,290000

View File

@@ -76,42 +76,8 @@
<!-- Skip to main content for accessibility --> <!-- Skip to main content for accessibility -->
<a href="#main-content" class="skip-to-main" style="position:absolute;left:-9999px;top:0;z-index:999;">跳转到主内容</a> <a href="#main-content" class="skip-to-main" style="position:absolute;left:-9999px;top:0;z-index:999;">跳转到主内容</a>
<!-- Navbar --> <!-- Navbar Component -->
<nav class="navbar"> <div id="navbar-component"></div>
<div class="nav-content">
<button class="mobile-toggle" id="mobile-toggle" aria-label="菜单">
<i class="fas fa-bars"></i>
</button>
<div class="logo">
<a href="/">
<img src="https://img.lunadeer.cn/i/2024/04/22/6625ce6c8ddc1.png" alt="白鹿原 Minecraft 服务器 Logo">
</a>
</div>
<div class="nav-links desktop-only">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html">赞助</a>
</div>
<div class="nav-cta-container">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439/doc/5yqg5ywl5pyn5yqh5zmo-WE4jkTxRmM" class="nav-cta">加入游戏</a>
</div>
</div>
</nav>
<!-- Mobile Menu -->
<div class="mobile-menu" id="mobile-menu">
<div class="mobile-menu-links">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html">赞助</a>
</div>
</div>
<!-- Hero Section --> <!-- Hero Section -->
<header id="main-content" class="hero" style="background-image: url('https://img.lunadeer.cn/i/2025/11/26/69267755e14e3.png');" role="banner"> <header id="main-content" class="hero" style="background-image: url('https://img.lunadeer.cn/i/2025/11/26/69267755e14e3.png');" role="banner">
@@ -260,15 +226,9 @@
</div> </div>
</section> </section>
<footer> <div id="footer-component"></div>
<div class="container">
<div class="footer-content">
<div class="footer-logo">白鹿原</div>
<p>&copy; 2026 白鹿原 Minecraft 服务器.</p>
</div>
</div>
</footer>
<script src="components.js"></script>
<script src="script.js"></script> <script src="script.js"></script>
</body> </body>
</html> </html>

View File

@@ -29,44 +29,9 @@ document.addEventListener('DOMContentLoaded', () => {
// setupModal(); // Removed, modal is gone // setupModal(); // Removed, modal is gone
fetchServerStatus(); fetchServerStatus();
startRuntimeTimer(); startRuntimeTimer();
setupMobileMenu();
}); });
function setupMobileMenu() {
const toggle = document.getElementById('mobile-toggle');
const menu = document.getElementById('mobile-menu');
if (toggle && menu) {
const icon = toggle.querySelector('i');
toggle.addEventListener('click', () => {
menu.classList.toggle('active');
document.body.classList.toggle('menu-open');
if (menu.classList.contains('active')) {
if(icon) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
}
} else {
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
}
});
menu.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
menu.classList.remove('active');
document.body.classList.remove('menu-open');
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
});
});
}
}
function startRuntimeTimer() { function startRuntimeTimer() {
const startTime = new Date("2021-09-14T09:57:59").getTime(); const startTime = new Date("2021-09-14T09:57:59").getTime();

View File

@@ -530,42 +530,7 @@
</head> </head>
<body> <body>
<!-- Navbar --> <div id="navbar-component"></div>
<nav class="navbar">
<div class="nav-content">
<button class="mobile-toggle" id="mobile-toggle" aria-label="菜单">
<i class="fas fa-bars"></i>
</button>
<div class="logo">
<a href="/">
<img src="https://img.lunadeer.cn/i/2024/04/22/6625ce6c8ddc1.png" alt="白鹿原 Minecraft 服务器 Logo">
</a>
</div>
<div class="nav-links desktop-only">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html" class="active" style="color: var(--text-primary); opacity: 1;">赞助</a>
</div>
<div class="nav-cta-container">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439/doc/5yqg5ywl5pyn5yqh5zmo-WE4jkTxRmM" class="nav-cta">加入游戏</a>
</div>
</div>
<!-- Mobile Menu Overlay -->
<div class="mobile-menu" id="mobile-menu">
<div class="mobile-nav-links">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html">数据</a>
<a href="/sponsor.html">赞助列表</a>
</div>
</div>
</nav>
<div class="sponsor-hero"> <div class="sponsor-hero">
<h1>感谢每一位支持者</h1> <h1>感谢每一位支持者</h1>
@@ -639,6 +604,8 @@
</div> </div>
</div> </div>
<div id="footer-component"></div>
<script src="components.js"></script>
<script src="sponsor_script.js"></script> <script src="sponsor_script.js"></script>
</body> </body>
</html> </html>

View File

@@ -13,29 +13,7 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
function setupUI() { function setupUI() {
// Mobile menu toggle // Mobile menu toggle handled by components.js
const toggle = document.getElementById('mobile-toggle');
const menu = document.getElementById('mobile-menu');
if (toggle && menu) {
const icon = toggle.querySelector('i');
toggle.addEventListener('click', () => {
menu.classList.toggle('active');
document.body.classList.toggle('menu-open');
if (menu.classList.contains('active')) {
if(icon) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
}
} else {
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
}
});
}
// Modal Logic // Modal Logic
const modal = document.getElementById('sponsor-modal'); const modal = document.getElementById('sponsor-modal');

View File

@@ -451,42 +451,7 @@
</head> </head>
<body> <body>
<!-- Navbar --> <div id="navbar-component"></div>
<nav class="navbar">
<div class="nav-content">
<button class="mobile-toggle" id="mobile-toggle" aria-label="菜单">
<i class="fas fa-bars"></i>
</button>
<div class="logo">
<a href="/">
<img src="https://img.lunadeer.cn/i/2024/04/22/6625ce6c8ddc1.png" alt="白鹿原 Minecraft 服务器 Logo">
</a>
</div>
<div class="nav-links desktop-only">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html" style="opacity: 1; font-weight: 600;">数据</a>
<a href="/sponsor.html">赞助</a>
</div>
<div class="nav-cta-container">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439/doc/5yqg5ywl5pyn5yqh5zmo-WE4jkTxRmM" class="nav-cta">加入游戏</a>
</div>
</div>
</nav>
<!-- Mobile Menu -->
<div class="mobile-menu" id="mobile-menu">
<div class="mobile-menu-links">
<a href="https://outline.lunadeer.cn/s/447e5db6-8af4-468e-b7c5-cdb7b48aa439">文档</a>
<a href="https://mcmap.lunadeer.cn/">地图</a>
<a href="https://mcphoto.lunadeer.cn/">相册</a>
<a href="https://qm.qq.com/q/9izlHDoef6">群聊</a>
<a href="/stats.html" style="font-weight: 600;">数据</a>
<a href="/sponsor.html">赞助列表</a>
</div>
</div>
<!-- Hero Section --> <!-- Hero Section -->
<header class="hero stats-hero" style="background-image: url('https://img.lunadeer.cn/i/2025/11/26/69267755e14e3.png');"> <header class="hero stats-hero" style="background-image: url('https://img.lunadeer.cn/i/2025/11/26/69267755e14e3.png');">
@@ -647,15 +612,9 @@
</div> </div>
</div> </div>
<footer> <div id="footer-component"></div>
<div class="container">
<div class="footer-content">
<div class="footer-logo">白鹿原</div>
<p>&copy; 2025 白鹿原 Minecraft 服务器.</p>
</div>
</div>
</footer>
<script src="components.js"></script>
<script src="stats_script.js"></script> <script src="stats_script.js"></script>
</body> </body>
</html> </html>

View File

@@ -3,44 +3,9 @@ document.addEventListener('DOMContentLoaded', () => {
setupModal(); setupModal();
setupSearch(); setupSearch();
setupLoadMore(); setupLoadMore();
setupMobileMenu();
}); });
function setupMobileMenu() {
const toggle = document.getElementById('mobile-toggle');
const menu = document.getElementById('mobile-menu');
if (toggle && menu) {
const icon = toggle.querySelector('i');
toggle.addEventListener('click', () => {
menu.classList.toggle('active');
document.body.classList.toggle('menu-open');
if (menu.classList.contains('active')) {
if(icon) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
}
} else {
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
}
});
menu.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
menu.classList.remove('active');
document.body.classList.remove('menu-open');
if(icon) {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
});
});
}
}
let allPlayers = []; let allPlayers = [];
let displayedPlayers = []; let displayedPlayers = [];

View File

@@ -848,3 +848,11 @@ footer {
overflow: hidden; overflow: hidden;
} }
} }
/* Active State for Navbar Links */
.nav-links a.active,
.mobile-menu-links a.active {
opacity: 1;
font-weight: 600;
color: var(--text-primary);
}