重构了main.html的主函数
重构了大量的页面的sidebar 优化了代码结构
This commit is contained in:
236
web/js/components/sidebar-loader.js
Normal file
236
web/js/components/sidebar-loader.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* 共享侧边栏加载器
|
||||
* 动态加载侧边栏组件,支持高亮当前页面
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// 侧边栏容器占位样式(防止加载时闪烁)
|
||||
const containerStyles = `
|
||||
#sidebar-container {
|
||||
width: 16rem;
|
||||
min-width: 16rem;
|
||||
height: 100vh;
|
||||
background-color: #001529;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
#sidebar-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// 侧边栏样式
|
||||
const sidebarStyles = `
|
||||
.sidebar-section-title {
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.75rem;
|
||||
color: rgba(191, 203, 217, 0.7);
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.nav-link:hover {
|
||||
background-color: rgba(0, 21, 41, 0.2);
|
||||
}
|
||||
.sidebar-item-active {
|
||||
background-color: rgba(24, 144, 255, 0.1) !important;
|
||||
color: #1890ff !important;
|
||||
border-left: 4px solid #1890ff;
|
||||
}
|
||||
.sidebar-slider {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 4px;
|
||||
height: 0;
|
||||
background-color: #1890ff;
|
||||
border-radius: 0 2px 2px 0;
|
||||
transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
opacity 0.3s ease;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
opacity: 0;
|
||||
}
|
||||
.nav-item-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.nav-link {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
// 立即注入容器样式(防止闪烁)
|
||||
(function injectContainerStyles() {
|
||||
const styleEl = document.createElement('style');
|
||||
styleEl.id = 'sidebar-container-styles';
|
||||
styleEl.textContent = containerStyles;
|
||||
document.head.appendChild(styleEl);
|
||||
})();
|
||||
|
||||
// 根据当前页面路径确定活动页面
|
||||
function getCurrentPage() {
|
||||
const path = window.location.pathname;
|
||||
const search = window.location.search;
|
||||
const fileName = path.split('/').pop().replace('.html', '');
|
||||
|
||||
// 检查 URL 参数
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const pageParam = urlParams.get('page');
|
||||
if (pageParam) {
|
||||
return pageParam;
|
||||
}
|
||||
|
||||
// 根据文件名映射
|
||||
const pageMap = {
|
||||
'main': 'fine-tune',
|
||||
'hardware': 'hardware',
|
||||
'logs': 'logs',
|
||||
'tools': 'tools',
|
||||
'fine-tune-create': 'fine-tune',
|
||||
'training-log': 'fine-tune',
|
||||
'dataset-create': 'dataset-manage',
|
||||
'dataset-preview': 'dataset-manage',
|
||||
'model-manage': 'model-manage',
|
||||
'model-manage-create': 'model-manage',
|
||||
'model-eval': 'model-eval',
|
||||
'model-eval-create': 'model-eval',
|
||||
'model-compare-create': 'model-compare',
|
||||
'model-compare-chat': 'model-compare',
|
||||
'model-compare-result': 'model-compare',
|
||||
'model-dimension-create': 'model-eval',
|
||||
'model-inference': 'model-manage',
|
||||
'custom-tool-create': 'tools'
|
||||
};
|
||||
|
||||
return pageMap[fileName] || 'fine-tune';
|
||||
}
|
||||
|
||||
// 加载侧边栏
|
||||
async function loadSidebar() {
|
||||
const container = document.getElementById('sidebar-container');
|
||||
if (!container) {
|
||||
console.warn('未找到 sidebar-container 元素');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 计算组件路径
|
||||
const currentPath = window.location.pathname;
|
||||
let basePath = '';
|
||||
if (currentPath.includes('/pages/')) {
|
||||
basePath = 'components/';
|
||||
} else {
|
||||
basePath = 'pages/components/';
|
||||
}
|
||||
|
||||
const response = await fetch(basePath + 'sidebar.html');
|
||||
if (!response.ok) {
|
||||
throw new Error('加载侧边栏失败: ' + response.status);
|
||||
}
|
||||
|
||||
const html = await response.text();
|
||||
container.innerHTML = html;
|
||||
|
||||
// 注入样式
|
||||
if (!document.getElementById('sidebar-styles')) {
|
||||
const styleEl = document.createElement('style');
|
||||
styleEl.id = 'sidebar-styles';
|
||||
styleEl.textContent = sidebarStyles;
|
||||
document.head.appendChild(styleEl);
|
||||
}
|
||||
|
||||
// 修正 logo 路径
|
||||
const logo = container.querySelector('#sidebar-logo');
|
||||
if (logo) {
|
||||
const depth = currentPath.split('/pages/').length > 1 ? '../' : '';
|
||||
logo.src = depth + 'assets/logo/logo.png';
|
||||
}
|
||||
|
||||
// 高亮当前页面
|
||||
const currentPage = window.sidebarCurrentPage || getCurrentPage();
|
||||
highlightCurrentPage(currentPage);
|
||||
|
||||
// 初始化滑块
|
||||
initSlider();
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载侧边栏出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 高亮当前页面
|
||||
function highlightCurrentPage(currentPage) {
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
const page = link.dataset.page;
|
||||
if (page === currentPage) {
|
||||
link.classList.add('sidebar-item-active');
|
||||
link.classList.remove('hover:bg-[#001529]/20', 'transition-colors');
|
||||
} else {
|
||||
link.classList.remove('sidebar-item-active');
|
||||
link.classList.add('hover:bg-[#001529]/20', 'transition-colors');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化滑块
|
||||
function initSlider() {
|
||||
const slider = document.getElementById('sidebar-slider');
|
||||
if (!slider) return;
|
||||
|
||||
// 找到当前活动项
|
||||
const activeLink = document.querySelector('.nav-link.sidebar-item-active');
|
||||
if (activeLink) {
|
||||
const wrapper = activeLink.closest('.nav-item-wrapper');
|
||||
if (wrapper) {
|
||||
updateSliderPosition(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定导航点击事件
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
const wrapper = this.closest('.nav-item-wrapper');
|
||||
if (wrapper) {
|
||||
updateSliderPosition(wrapper);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 更新滑块位置
|
||||
function updateSliderPosition(targetWrapper) {
|
||||
const slider = document.getElementById('sidebar-slider');
|
||||
if (!slider || !targetWrapper) return;
|
||||
|
||||
const nav = document.querySelector('nav');
|
||||
if (!nav) return;
|
||||
|
||||
const navRect = nav.getBoundingClientRect();
|
||||
const wrapperRect = targetWrapper.getBoundingClientRect();
|
||||
|
||||
const top = wrapperRect.top - navRect.top + nav.scrollTop;
|
||||
const height = wrapperRect.height;
|
||||
|
||||
slider.style.top = top + 'px';
|
||||
slider.style.height = height + 'px';
|
||||
slider.style.opacity = '1';
|
||||
}
|
||||
|
||||
// 导出到全局
|
||||
window.SidebarLoader = {
|
||||
load: loadSidebar,
|
||||
highlight: highlightCurrentPage,
|
||||
getCurrentPage: getCurrentPage
|
||||
};
|
||||
|
||||
// DOM 加载完成后自动加载侧边栏
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', loadSidebar);
|
||||
} else {
|
||||
loadSidebar();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user