feat: 所有页面支持1到4层级的嵌套结构
This commit is contained in:
134
src/script.js
134
src/script.js
@@ -342,6 +342,137 @@ window.MeNav = {
|
||||
}
|
||||
};
|
||||
|
||||
// 多层级嵌套书签功能
|
||||
window.MeNav.expandAll = function() {
|
||||
document.querySelectorAll('.category.collapsed, .group.collapsed').forEach(element => {
|
||||
element.classList.remove('collapsed');
|
||||
saveToggleState(element, 'expanded');
|
||||
});
|
||||
};
|
||||
|
||||
window.MeNav.collapseAll = function() {
|
||||
document.querySelectorAll('.category:not(.collapsed), .group:not(.collapsed)').forEach(element => {
|
||||
element.classList.add('collapsed');
|
||||
saveToggleState(element, 'collapsed');
|
||||
});
|
||||
};
|
||||
|
||||
window.MeNav.toggleCategory = function(categoryName, subcategoryName = null, groupName = null) {
|
||||
const selector = groupName
|
||||
? `[data-name="${categoryName}"] [data-name="${subcategoryName}"] [data-name="${groupName}"]`
|
||||
: subcategoryName
|
||||
? `[data-name="${categoryName}"] [data-name="${subcategoryName}"]`
|
||||
: `[data-name="${categoryName}"]`;
|
||||
|
||||
const element = document.querySelector(selector);
|
||||
if (element) {
|
||||
toggleNestedElement(element);
|
||||
}
|
||||
};
|
||||
|
||||
window.MeNav.getNestedStructure = function() {
|
||||
// 返回完整的嵌套结构数据
|
||||
const categories = [];
|
||||
document.querySelectorAll('.category-level-1').forEach(cat => {
|
||||
categories.push(extractNestedData(cat));
|
||||
});
|
||||
return categories;
|
||||
};
|
||||
|
||||
// 切换嵌套元素
|
||||
function toggleNestedElement(container) {
|
||||
const isCollapsed = container.classList.contains('collapsed');
|
||||
|
||||
if (isCollapsed) {
|
||||
container.classList.remove('collapsed');
|
||||
saveToggleState(container, 'expanded');
|
||||
} else {
|
||||
container.classList.add('collapsed');
|
||||
saveToggleState(container, 'collapsed');
|
||||
}
|
||||
|
||||
// 触发自定义事件
|
||||
const event = new CustomEvent('nestedToggle', {
|
||||
detail: {
|
||||
element: container,
|
||||
type: container.dataset.type,
|
||||
name: container.dataset.name,
|
||||
isCollapsed: !isCollapsed
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
// 保存切换状态
|
||||
function saveToggleState(element, state) {
|
||||
const type = element.dataset.type;
|
||||
const name = element.dataset.name;
|
||||
const level = element.dataset.level || '1';
|
||||
const key = `menav-toggle-${type}-${level}-${name}`;
|
||||
localStorage.setItem(key, state);
|
||||
}
|
||||
|
||||
// 恢复切换状态
|
||||
function restoreToggleState(element) {
|
||||
const type = element.dataset.type;
|
||||
const name = element.dataset.name;
|
||||
const level = element.dataset.level || '1';
|
||||
const key = `menav-toggle-${type}-${level}-${name}`;
|
||||
const savedState = localStorage.getItem(key);
|
||||
|
||||
if (savedState === 'collapsed') {
|
||||
element.classList.add('collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化嵌套分类
|
||||
function initializeNestedCategories() {
|
||||
// 为所有可折叠元素添加切换功能
|
||||
document.querySelectorAll('[data-toggle="category"], [data-toggle="group"]').forEach(header => {
|
||||
header.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
const container = this.parentElement;
|
||||
toggleNestedElement(container);
|
||||
});
|
||||
|
||||
// 恢复保存的状态
|
||||
restoreToggleState(header.parentElement);
|
||||
});
|
||||
}
|
||||
|
||||
// 提取嵌套数据
|
||||
function extractNestedData(element) {
|
||||
const data = {
|
||||
name: element.dataset.name,
|
||||
type: element.dataset.type,
|
||||
level: element.dataset.level,
|
||||
isCollapsed: element.classList.contains('collapsed')
|
||||
};
|
||||
|
||||
// 提取子元素数据
|
||||
const subcategories = element.querySelectorAll(':scope > .category-content > .subcategories-container > .category');
|
||||
if (subcategories.length > 0) {
|
||||
data.subcategories = Array.from(subcategories).map(sub => extractNestedData(sub));
|
||||
}
|
||||
|
||||
const groups = element.querySelectorAll(':scope > .category-content > .groups-container > .group');
|
||||
if (groups.length > 0) {
|
||||
data.groups = Array.from(groups).map(group => extractNestedData(group));
|
||||
}
|
||||
|
||||
const sites = element.querySelectorAll(':scope > .category-content > .sites-grid > .site-card, :scope > .group-content > .sites-grid > .site-card');
|
||||
if (sites.length > 0) {
|
||||
data.sites = Array.from(sites).map(site => ({
|
||||
name: site.dataset.name,
|
||||
url: site.dataset.url,
|
||||
icon: site.dataset.icon,
|
||||
description: site.dataset.description
|
||||
}));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 先声明所有状态变量
|
||||
let isSearchActive = false;
|
||||
@@ -1312,6 +1443,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化嵌套分类功能
|
||||
initializeNestedCategories();
|
||||
|
||||
// 初始化搜索索引(使用requestIdleCallback或setTimeout延迟初始化,避免影响页面加载)
|
||||
if ('requestIdleCallback' in window) {
|
||||
requestIdleCallback(() => initSearchIndex());
|
||||
|
||||
Reference in New Issue
Block a user