Skip to content

Commit efe27fa

Browse files
committed
优化手风琴目录效果
1 parent f48fcaa commit efe27fa

2 files changed

Lines changed: 63 additions & 35 deletions

File tree

src/components/toc/AccordionTOC.astro

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ const { headings, position = 'left', class: className } = Astro.props
4848
border-left: 3px solid #3b82f6 !important;
4949
color: #2563eb !important;
5050
}
51+
:root:is([data-theme='light'], [data-theme='system']) .toc-accordion.right .toc-menu-item.active{
52+
border-left: none !important;
53+
border-right: 3px solid #3b82f6 !important;
54+
}
5155

5256
.toc-accordion {
5357
position: fixed;
@@ -75,6 +79,16 @@ const { headings, position = 'left', class: className } = Astro.props
7579
background: transparent;
7680
min-width: 44px;
7781
min-height: 120px;
82+
border-radius: 12px;
83+
transition: background-color 0.3s ease;
84+
}
85+
86+
.toc-lines:hover {
87+
background: hsl(var(--primary) / 0.1);
88+
backdrop-filter: blur(5px);
89+
cursor: pointer;
90+
border: 1px solid hsl(var(--primary) / 0.2);
91+
transform: scale(1.02);
7892
}
7993

8094
.toc-accordion.right .toc-lines {
@@ -176,10 +190,7 @@ const { headings, position = 'left', class: className } = Astro.props
176190
word-break: break-all !important;
177191
}
178192
.toc-full-menu-content{
179-
padding: 24px 12px 24px 0 !important; /* 右边距12px,左边距0,内容更贴近左侧 */
180-
}
181-
.toc-accordion.right .toc-full-menu-content{
182-
padding: 24px 0 24px 12px !important; /* 右侧模式,左边距12px,右边距0 */
193+
padding: 24px 12px 24px 12px !important; /* 两端对齐 */
183194
}
184195
.toc-full-menu::-webkit-scrollbar {
185196
width: 6px;
@@ -213,7 +224,7 @@ const { headings, position = 'left', class: className } = Astro.props
213224
border-left-color: transparent;
214225
border-right-color: var(--toc-menu-bg, rgba(30, 30, 30, 0.95));
215226
}
216-
.toc-accordion:hover .toc-full-menu{
227+
.toc-full-menu.show{
217228
opacity: 1 !important;
218229
transform: translateX(0) !important;
219230
pointer-events: auto !important;
@@ -235,34 +246,40 @@ const { headings, position = 'left', class: className } = Astro.props
235246
border-left: 3px solid #3b82f6 !important;
236247
color: var(--toc-menu-active-color) !important;
237248
}
249+
.toc-accordion.right .toc-menu-item.active{
250+
border-left: none !important;
251+
border-right: 3px solid #3b82f6 !important;
252+
}
238253
.toc-menu-item.level-1{
239254
font-weight: 600 !important;
240255
margin-left: 0 !important;
241256
}
242257
.toc-menu-item.level-2{
243-
margin-left: 15px !important;
258+
margin-left: 10px !important;
244259
font-size: 12px !important;
245260
}
246261
.toc-menu-item.level-3{
247-
margin-left: 30px !important;
262+
margin-left: 20px !important;
248263
font-size: 11px !important;
249264
opacity: 0.9 !important;
250265
}
251266
.toc-menu-item.level-4{
252-
margin-left: 45px !important;
267+
margin-left: 30px !important;
253268
font-size: 11px !important;
254269
opacity: 0.8 !important;
255270
}
256271
.toc-menu-item.level-5{
257-
margin-left: 60px !important;
272+
margin-left: 40px !important;
258273
font-size: 10px !important;
259274
opacity: 0.7 !important;
260275
}
261276
.toc-menu-item.level-6{
262-
margin-left: 75px !important;
277+
margin-left: 50px !important;
263278
font-size: 10px !important;
264279
opacity: 0.6 !important;
265280
}
281+
282+
/* 右侧模式下保持与左侧相同的层级缩进效果 */
266283
.toc-menu-level-indicator{
267284
display: inline-block !important;
268285
width: 8px !important;
@@ -350,7 +367,7 @@ const { headings, position = 'left', class: className } = Astro.props
350367
return {
351368
element: el,
352369
level: heading.depth,
353-
text: heading.text,
370+
text: heading.text.replace(/#/g, '').trim(),
354371
id: heading.slug || `heading-${idx}`,
355372
top: el ? el.offsetTop : 0
356373
}
@@ -396,7 +413,7 @@ const { headings, position = 'left', class: className } = Astro.props
396413
this._menuClickBound = true
397414
}
398415
}
399-
bindEvents() {
416+
bindEvents() {
400417
this.tocLines.addEventListener('click', (e) => {
401418
const line = e.target.closest('.toc-line')
402419
if (line) {
@@ -411,32 +428,32 @@ const { headings, position = 'left', class: className } = Astro.props
411428
}
412429
}
413430
})
414-
// 支持“锁定”menu,点击 toc-accordion 区域可锁定/解锁
415-
this.menuLocked = false
416-
this.toc.addEventListener('mouseenter', () => {
417-
if (!this.menuLocked) {
418-
this.isMenuVisible = true
431+
432+
// 点击目录按钮区域控制浮窗显示/隐藏
433+
this.toc.addEventListener('click', (e) => {
434+
// 如果点击的是浮窗内容,不处理
435+
if (e.target.closest('.toc-full-menu')) return
436+
437+
// 切换浮窗显示状态
438+
this.isMenuVisible = !this.isMenuVisible
439+
440+
if (this.isMenuVisible) {
419441
this.tocFullMenu.classList.add('show')
420442
this.scrollToActiveItem()
443+
} else {
444+
this.tocFullMenu.classList.remove('show')
421445
}
422446
})
423-
// 移除 menu hover 消失逻辑,确保点击后不会因 hover 离开而消失
424-
// this.toc.addEventListener('mouseleave', ...)
425-
// this.tocFullMenu.addEventListener('mouseleave', ...)
426-
this.toc.addEventListener('click', (e) => {
427-
if (e.target.closest('.toc-full-menu')) return
428-
this.menuLocked = !this.menuLocked
429-
this.isMenuVisible = this.menuLocked || this.isMenuVisible
430-
if (this.menuLocked) this.scrollToActiveItem()
431-
if (!this.menuLocked) this.tocFullMenu.classList.remove('show')
432-
})
447+
448+
// 点击外部区域关闭浮窗
433449
document.addEventListener('click', (e) => {
434450
if (!this.toc.contains(e.target)) {
435-
this.menuLocked = false
436451
this.isMenuVisible = false
437452
this.tocFullMenu.classList.remove('show')
438453
}
439454
})
455+
456+
// 滚动时更新活跃状态
440457
let ticking = false
441458
window.addEventListener(
442459
'scroll',
@@ -451,6 +468,8 @@ const { headings, position = 'left', class: className } = Astro.props
451468
},
452469
{ passive: true }
453470
)
471+
472+
// 窗口大小改变时重新计算位置
454473
window.addEventListener('resize', () => {
455474
this.recalculatePositions()
456475
})
@@ -481,14 +500,14 @@ const { headings, position = 'left', class: className } = Astro.props
481500
item.classList.toggle('active', index === activeIndex)
482501
})
483502
this.currentActiveIndex = activeIndex
484-
if (this.isMenuVisible || this.menuLocked) {
503+
if (this.isMenuVisible) {
485504
this.scrollToActiveItem()
486505
}
487506
}
488507
}
489508
scrollToActiveItem() {
490509
// 只滚动 menu 区域,不滚动正文
491-
if (this.currentActiveIndex >= 0 && (this.isMenuVisible || this.menuLocked)) {
510+
if (this.currentActiveIndex >= 0 && this.isMenuVisible) {
492511
const activeMenuItem = this.tocFullMenuContent.children[this.currentActiveIndex]
493512
if (activeMenuItem) {
494513
const menuHeight = this.tocFullMenu.clientHeight

src/pages/about/index.astro

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ import ToolSection from '@/components/tools/ToolSection.astro'
100100
tools={[
101101
{
102102
name: 'VS Code',
103-
description: 'IDE',
103+
description: 'powerful code editor',
104104
href: 'https://code.visualstudio.com/',
105105
icon: import('@/assets/tools/vscode.svg?raw')
106106
},
107107
{
108-
name: 'Idea',
109-
description: 'Intellij IDEA',
110-
href: 'https://nodejs.org/',
108+
name: 'Intellij IDEA',
109+
description: 'Best Java IDE',
110+
href: 'https://www.jetbrains.com/idea/',
111111
icon: import('@/assets/tools/idea.svg?raw')
112112
},
113113
{
@@ -136,7 +136,16 @@ import ToolSection from '@/components/tools/ToolSection.astro'
136136
link: 'https://github.com/catcodeme',
137137
text: 'followers',
138138
api: 'github/catcodeme'
139-
}
139+
},
140+
{
141+
platform: 'Bilibili',
142+
icon: 'bilibili',
143+
link: 'https://space.bilibili.com/19080963',
144+
text: 'fans',
145+
// api: 'bilibili/19080963',
146+
color: '#fe7398',
147+
count: 18
148+
},
140149
]}
141150
/>
142151

0 commit comments

Comments
 (0)