文件
parlz-domain/doc/script.js
T

198 行
7.1 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
const markdownBody = document.getElementById('markdownBody');
const rawContent = markdownBody.innerHTML;
markdownBody.innerHTML = marked.parse(rawContent);
const themeToggle = document.getElementById('themeToggle');
const mobileThemeToggle = document.getElementById('mobileThemeToggle');
const html = document.documentElement;
function setTheme(theme) {
html.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}
function toggleTheme() {
const current = html.getAttribute('data-theme');
setTheme(current === 'dark' ? 'light' : 'dark');
}
const saved = localStorage.getItem('theme');
if (saved) {
setTheme(saved);
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
setTheme('dark');
}
themeToggle.addEventListener('click', toggleTheme);
if (mobileThemeToggle) mobileThemeToggle.addEventListener('click', toggleTheme);
const menuToggle = document.getElementById('menuToggle');
const sidebar = document.querySelector('.sidebar');
const overlay = document.getElementById('overlay');
if (menuToggle) {
menuToggle.addEventListener('click', function() {
sidebar.classList.toggle('open');
overlay.classList.toggle('show');
});
}
if (overlay) {
overlay.addEventListener('click', function() {
sidebar.classList.remove('open');
overlay.classList.remove('show');
});
}
const folders = document.querySelectorAll('.folder-toggle');
folders.forEach(function(folder) {
folder.addEventListener('click', function() {
const li = this.parentElement;
li.classList.toggle('open');
});
});
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.addEventListener('input', function() {
const query = this.value.toLowerCase().trim();
const files = document.querySelectorAll('.nav-tree .file');
const dirs = document.querySelectorAll('.nav-tree .folder');
if (!query) {
files.forEach(f => f.classList.remove('hidden'));
dirs.forEach(d => d.classList.remove('hidden'));
return;
}
files.forEach(function(file) {
const text = file.textContent.toLowerCase();
if (text.includes(query)) {
file.classList.remove('hidden');
let parent = file.parentElement;
while (parent) {
if (parent.classList && parent.classList.contains('folder')) {
parent.classList.remove('hidden');
parent.classList.add('open');
}
parent = parent.parentElement;
}
} else {
file.classList.add('hidden');
}
});
dirs.forEach(function(dir) {
const visibleFiles = dir.querySelectorAll('.file:not(.hidden)');
if (visibleFiles.length === 0) {
const folderText = dir.querySelector('.folder-toggle').textContent.toLowerCase();
if (!folderText.includes(query)) {
dir.classList.add('hidden');
}
}
});
});
}
const currentFile = document.querySelector('.nav-tree .file.active');
if (currentFile) {
let parent = currentFile.parentElement;
while (parent) {
if (parent.classList && parent.classList.contains('folder')) {
parent.classList.add('open');
}
parent = parent.parentElement;
}
currentFile.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
const navTree = document.getElementById('navTree');
if (navTree) {
navTree.addEventListener('click', function(e) {
const link = e.target.closest('a');
if (!link) return;
const href = link.getAttribute('href');
if (!href || href.startsWith('http') || href.startsWith('#') || href.startsWith('javascript')) return;
e.preventDefault();
const sidebarEl = document.querySelector('.sidebar');
const overlayEl = document.getElementById('overlay');
if (sidebarEl.classList.contains('open')) {
sidebarEl.classList.remove('open');
overlayEl.classList.remove('show');
}
history.pushState(null, '', href);
loadDoc(href);
});
}
// ===== 使用 XMLHttpRequest 替代 fetch =====
function loadDoc(href) {
var url = '/doc/index.php' + href + '&_ajax=1';
markdownBody.style.opacity = '0.5';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.timeout = 30000; // 30秒超时
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
markdownBody.style.opacity = '1';
if (xhr.status === 200) {
var data = xhr.responseText;
// 检查是否返回了 HTML(说明请求失败)
if (data.trim().startsWith('<!DOCTYPE') || data.trim().startsWith('<html')) {
// 降级:直接跳转
window.location.href = href;
return;
}
markdownBody.innerHTML = marked.parse(data);
var titleEl = markdownBody.querySelector('h1');
var newTitle = titleEl ? titleEl.textContent + ' - Docs' : 'Docs - Docs';
document.title = newTitle;
updateActiveLink(href);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
// 请求失败,降级跳转
console.error('加载失败,状态码: ' + xhr.status);
window.location.href = href;
}
}
};
xhr.onerror = function() {
markdownBody.style.opacity = '1';
console.error('网络错误');
window.location.href = href;
};
xhr.ontimeout = function() {
markdownBody.style.opacity = '1';
console.error('请求超时');
window.location.href = href;
};
xhr.send();
}
function updateActiveLink(href) {
document.querySelectorAll('.nav-tree .file').forEach(function(f) {
f.classList.remove('active');
var a = f.querySelector('a');
if (a && a.getAttribute('href') === href) {
f.classList.add('active');
}
});
}
window.addEventListener('popstate', function() {
var params = new URLSearchParams(window.location.search);
var f = params.get('file');
if (f) {
loadDoc('?file=' + f);
}
});
});