-
Notifications
You must be signed in to change notification settings - Fork 167
Expand file tree
/
Copy pathindex.html
More file actions
489 lines (433 loc) · 18.8 KB
/
index.html
File metadata and controls
489 lines (433 loc) · 18.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JavaWeb项目源码库 | 从零到架构师一站搞定</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="超全JavaWeb项目源码库,9年经验Java专家亲选,100+可运行项目,持续更新维护">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
<style>
:root {
--theme-color: #42b983;
}
.sidebar-nav li {
margin: 6px 0;
}
.markdown-section {
max-width: 900px;
}
.markdown-section code {
color: #e96900;
}
.app-name-link img {
max-width: 80%;
}
.cover-main h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.cover-main blockquote {
border-left: 4px solid var(--theme-color);
}
.markdown-section h2 {
margin-top: 2rem;
}
</style>
</head>
<body>
<div id="app"></div>
<script>
// 动态设置basePath,适配本地开发和GitHub Pages部署
// 改进GitHub Pages环境检测逻辑
const isGitHubPages = window.location.hostname.includes('github.io');
const repoPath = '/JavaWeb-Project-Source-Share/';
// 记录环境信息用于调试
console.log('[Docsify配置] 当前环境:', window.location.hostname);
console.log('[Docsify配置] 路径:', window.location.pathname);
console.log('[Docsify配置] 识别为GitHub Pages:', isGitHubPages);
// 确定基础路径
const basePath = isGitHubPages ? repoPath : './';
console.log('[Docsify配置] 使用basePath:', basePath);
// 创建全面的alias映射,确保GitHub Pages环境下所有文件都能正确加载
const aliasMap = {
// 基础文件映射
'/_sidebar.md': '/_sidebar.md',
'/_coverpage.md': '/_coverpage.md',
'/README.md': '/README.md',
'/_404.md': '/_404.md',
// 为GitHub Pages环境添加特殊映射
[repoPath + '_sidebar.md']: '/_sidebar.md',
[repoPath + '_coverpage.md']: '/_coverpage.md',
[repoPath + 'README.md']: '/README.md',
[repoPath + '_404.md']: '/_404.md',
// 处理子目录中的特殊文件引用
'/.*/_sidebar.md': '/_sidebar.md',
'/.*/_coverpage.md': '/_coverpage.md'
};
window.$docsify = {
name: 'JavaWeb项目源码库',
repo: 'coderzcr/JavaWeb-Project-Source-Share',
loadSidebar: true,
subMaxLevel: 0,
auto2top: true,
coverpage: true,
basePath: basePath,
homepage: 'README.md',
relativePath: true, // 启用相对路径处理
alias: aliasMap,
// 添加钩子函数来处理路径问题
hooks: {
// 路由钩子,处理路径规范化
beforeEach: function (router) {
console.log('[路由钩子] 当前路由:', router);
// 确保路径正确,处理GitHub Pages环境下的路径问题
if (isGitHubPages && !router.path.includes(repoPath)) {
console.log('[路由钩子] 修正GitHub Pages路径');
// 这里可以进行路径修正
}
},
// 页面渲染完成后的钩子
afterEach: function (html, next) {
console.log('[渲染钩子] 页面渲染完成');
// 确保目录生成
setTimeout(createTableOfContents, 100);
next(html);
}
},
search: {
maxAge: 86400000,
paths: 'auto',
placeholder: '搜索',
noData: '没有找到结果',
depth: 6,
},
pagination: {
previousText: '上一章节',
nextText: '下一章节',
}
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-pagination/dist/docsify-pagination.min.js"></script>
<!-- 添加路径规范化脚本,使用统一的basePath处理所有环境 -->
<script>
// 页面加载完成后执行路径规范化
window.addEventListener('load', function() {
console.log('[路径规范化] 页面加载完成,开始处理链接和图片');
// 定期检查并修正页面中的链接和图片
function normalizePaths() {
// 获取所有内部链接
const links = document.querySelectorAll('a[href^="/"], a[href^="newcomer/"], a[href^="easy/"], a[href^="medium/"], a[href^="difficult/"], a[href^="expert/"]');
console.log('[路径规范化] 找到链接数量:', links.length);
links.forEach(link => {
let href = link.getAttribute('href');
console.log('[路径规范化] 处理链接:', href);
// 统一使用basePath处理所有链接,无需区分环境
// 先检查是否已经包含basePath,避免重复添加
if (href.startsWith('/') && !href.startsWith(basePath)) {
// 对于以/开头的链接,确保使用正确的basePath
const newHref = basePath + href.substring(1);
link.setAttribute('href', newHref);
console.log('[路径规范化] 修正链接:', href, '->', newHref);
} else if (['newcomer/', 'easy/', 'medium/', 'difficult/', 'expert/'].some(prefix => href.startsWith(prefix)) && !href.startsWith(basePath)) {
// 对于直接以目录开头的链接,添加basePath前缀
const newHref = basePath + href;
link.setAttribute('href', newHref);
console.log('[路径规范化] 修正相对链接:', href, '->', newHref);
}
});
// 处理图片路径,完全依赖basePath,不区分环境
const images = document.querySelectorAll('img[src^="../public/"]');
console.log('[路径规范化] 找到相对路径图片数量:', images.length);
images.forEach(img => {
let src = img.getAttribute('src');
console.log('[路径规范化] 处理图片路径:', src);
// 先检查是否已经处理过,避免重复添加
if (src.startsWith('../public/') && !src.startsWith(basePath)) {
// 统一处理:提取public/后的部分,添加到basePath后面
const imgPath = src.substring(11); // 移除 '../public/' 前缀
const normalizedSrc = basePath + 'public/' + imgPath;
img.setAttribute('src', normalizedSrc);
console.log('[路径规范化] 修正图片路径:', src, '->', normalizedSrc);
}
});
}
// 立即执行一次
normalizePaths();
// 定期执行,确保动态内容加载后的路径也被修正
setInterval(normalizePaths, 1000);
// 监听hash变化,确保页面切换后也能正确处理
window.addEventListener('hashchange', function() {
console.log('[路径规范化] Hash变化:', window.location.hash);
setTimeout(normalizePaths, 100);
});
});
</script>
<!-- 文章内目录生成插件 -->
<script>
// 简化的目录生成函数
function createTableOfContents() {
console.log('[目录插件] 尝试生成文章内目录');
// 直接操作DOM
setTimeout(function() {
// 查找内容区域
const content = document.querySelector('.markdown-section');
if (!content) {
console.log('[目录插件] 未找到内容区域,稍后重试');
return false;
}
// 移除可能存在的旧目录
const oldToc = document.querySelector('.article-toc');
if (oldToc) {
console.log('[目录插件] 移除旧目录');
oldToc.remove();
}
// 获取所有标题
const headings = content.querySelectorAll('h1, h2');
console.log('[目录插件] 找到标题数量:', headings.length);
if (headings.length === 0) {
console.log('[目录插件] 没有找到标题,不生成目录');
return false;
}
// 创建美观的目录容器
const tocContainer = document.createElement('div');
tocContainer.className = 'article-toc';
// 使用新的美观样式
tocContainer.style.cssText = `
background-color: #f8f9fa;
border-radius: 12px;
padding: 25px;
margin: 30px 0;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
position: relative;
z-index: 100;
border: 1px solid #eaecef;
`;
// 创建标题和列表
tocContainer.innerHTML = `
<h2 style="
margin-top: 0;
text-align: center;
color: #333;
font-size: 18px;
margin-bottom: 20px;
padding-bottom: 12px;
border-bottom: 2px solid #42b983;
font-weight: 600;
">文章目录</h2>
<ul style="
list-style-type: none;
padding-left: 0;
margin: 0;
"></ul>
`;
const list = tocContainer.querySelector('ul');
// 为每个标题创建目录项
headings.forEach((heading, index) => {
// 确保标题有ID
if (!heading.id) {
heading.id = 'toc-' + Date.now() + '-' + index;
console.log('[目录插件] 为标题设置ID:', heading.id);
}
const listItem = document.createElement('li');
// 根据标题级别设置样式
if (heading.tagName === 'H1') {
listItem.style.cssText = `
font-weight: bold;
font-size: 16px;
margin: 12px 0;
padding-left: 0;
`;
} else if (heading.tagName === 'H2') {
listItem.style.cssText = `
font-weight: 500;
font-size: 14px;
margin: 8px 0;
padding-left: 15px;
`;
}
// 创建链接
const link = document.createElement('a');
link.href = '#' + heading.id;
link.textContent = heading.textContent.trim();
link.style.cssText = `
display: block;
padding: 10px 15px;
text-decoration: none !important;
color: #555;
border-radius: 6px;
transition: all 0.25s ease;
background-color: transparent;
`;
// 悬停效果
link.onmouseover = function() {
this.style.backgroundColor = 'rgba(66, 185, 131, 0.1)';
this.style.color = '#42b983';
this.style.paddingLeft = '20px';
};
link.onmouseout = function() {
this.style.backgroundColor = 'transparent';
this.style.color = '#555';
this.style.paddingLeft = '15px';
};
// 点击事件 - 平滑滚动
link.onclick = function(e) {
e.preventDefault();
console.log('[目录插件] 点击目录项,滚动到:', heading.id);
const target = document.getElementById(heading.id);
if (target) {
// 高级滚动定位算法,确保标题准确显示在理想位置
// 获取标题级别
const level = parseInt(heading.tagName.substring(1));
// 计算视口位置(调整为视口中心位置)
const viewportHeight = window.innerHeight;
const idealViewportPosition = viewportHeight * 0.5; // 设置为0.5,让标题在视口中居中显示
// 获取目标元素在视口中的位置
const targetRect = target.getBoundingClientRect();
// 计算当前滚动位置
const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
// 根据标题级别调整偏移量
let levelOffset = 0;
if (level === 1) levelOffset = 30;
else if (level === 2) levelOffset = 20;
else if (level === 3) levelOffset = 10;
else levelOffset = 5;
// 计算最终滚动位置
const targetScrollTop = currentScrollTop + targetRect.top - idealViewportPosition - levelOffset;
console.log(`[目录插件] 滚动计算 - 级别: ${level}, 当前滚动: ${currentScrollTop}, 目标偏移: ${targetRect.top}, 理想位置: ${idealViewportPosition}, 最终位置: ${targetScrollTop}`);
// 执行平滑滚动
window.scrollTo({
top: Math.max(0, targetScrollTop), // 确保不小于0
behavior: 'smooth'
});
// 滚动完成后的微调逻辑
// 平滑滚动完成后(约800ms后)检查实际位置并微调,确保居中
setTimeout(() => {
// 再次获取目标元素的位置
const newTargetRect = target.getBoundingClientRect();
const newScrollTop = window.pageYOffset || document.documentElement.scrollTop;
// 计算实际位置与理想位置的差值
const positionDiff = newTargetRect.top - idealViewportPosition;
// 如果差值超过阈值(3px),进行微调
if (Math.abs(positionDiff) > 3) {
console.log(`[目录插件] 微调滚动位置 - 差值: ${positionDiff}`);
// 微调时使用非平滑滚动以避免抖动
window.scrollTo({
top: newScrollTop - positionDiff,
behavior: 'auto'
});
}
}, 800); // 增加延迟时间,确保滚动完全完成
// 高亮当前活动项
setTimeout(() => {
const allLinks = document.querySelectorAll('.article-toc a');
allLinks.forEach(a => {
a.style.backgroundColor = 'transparent';
a.style.color = '#555';
});
this.style.backgroundColor = 'rgba(66, 185, 131, 0.1)';
this.style.color = '#42b983';
}, 100);
}
};
listItem.appendChild(link);
list.appendChild(listItem);
});
// 将目录添加到内容区域的最前面
content.insertBefore(tocContainer, content.firstChild);
console.log('[目录插件] 目录已成功添加到页面');
return true;
}, 0);
}
// 核心: 在页面加载完成后设置定时器不断检查
window.addEventListener('DOMContentLoaded', function() {
console.log('[目录插件] 页面DOM加载完成');
// 立即尝试一次
createTableOfContents();
// 设置定时器定期检查,确保在docsify动态加载内容后也能生成目录
let checkTimer = setInterval(function() {
const content = document.querySelector('.markdown-section');
const tocExists = document.querySelector('.article-toc');
if (content && !tocExists) {
console.log('[目录插件] 定时器检测到内容区域,尝试生成目录');
const success = createTableOfContents();
if (success) {
clearInterval(checkTimer);
console.log('[目录插件] 目录生成成功,清除定时器');
}
} else if (tocExists) {
// 如果目录已经存在,清除定时器
clearInterval(checkTimer);
console.log('[目录插件] 目录已存在,清除定时器');
}
}, 500); // 每500毫秒检查一次
// 设置超时,避免无限循环
setTimeout(function() {
clearInterval(checkTimer);
console.log('[目录插件] 定时器超时,停止检查');
}, 10000); // 10秒后超时
});
// 添加键盘快捷键,按T键也可以手动生成目录
document.addEventListener('keydown', function(e) {
// 按下T键(非输入框中)
if (e.key === 't' && !['INPUT', 'TEXTAREA'].includes(e.target.tagName)) {
e.preventDefault();
console.log('[目录插件] 按下T键,手动生成目录');
createTableOfContents();
}
});
// 增强目录检测逻辑,确保在docsify环境中能正常工作
function enhanceTocDetection() {
console.log('[目录插件] 增强目录检测逻辑已启动');
// 监听全局点击事件,当用户导航到新页面时重新生成目录
document.addEventListener('click', function(e) {
// 检查是否点击了导航链接
const navLink = e.target.closest('.sidebar-nav a, .pagination-item a');
if (navLink) {
console.log('[目录插件] 检测到导航点击,将在页面更新后重新生成目录');
setTimeout(() => {
const checkNavTimer = setInterval(() => {
const content = document.querySelector('.markdown-section');
if (content) {
createTableOfContents();
clearInterval(checkNavTimer);
}
}, 100);
setTimeout(() => clearInterval(checkNavTimer), 3000);
}, 200);
}
});
// 监听URL变化(hash变化),因为docsify使用hash路由
window.addEventListener('hashchange', function() {
console.log('[目录插件] 检测到URL hash变化,尝试重新生成目录');
setTimeout(createTableOfContents, 100);
});
// 尝试安全地访问docsify的钩子系统
try {
if (window.$docsify && window.$docsify.hooks && typeof window.$docsify.hooks === 'object') {
console.log('[目录插件] 成功访问docsify钩子系统');
// 使用安全的方式设置钩子
if (typeof window.$docsify.hooks.doneEach === 'function') {
window.$docsify.hooks.doneEach(function() {
console.log('[目录插件] docsify doneEach钩子触发,生成目录');
createTableOfContents();
});
} else {
console.log('[目录插件] doneEach钩子不可用,使用备选方案');
}
} else {
console.log('[目录插件] 无法访问docsify钩子系统,使用备选方案');
}
} catch (error) {
console.warn('[目录插件] 访问docsify钩子时出错:', error);
}
}
// 启动增强的检测逻辑
enhanceTocDetection();
</script>
</body>