Files
YG_FT_Platform/web/js/components/sidebar-loader.js
WIN-JHFT4D3SIVT\caoxiaozhu 513e96082c 重构了main.html的主函数
重构了大量的页面的sidebar
优化了代码结构
2026-02-02 09:22:52 +08:00

237 lines
7.4 KiB
JavaScript

/**
* 共享侧边栏加载器
* 动态加载侧边栏组件,支持高亮当前页面
*/
(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();
}
})();