这篇文章主要用于记录写博客文章中常用的Markdown语法与Butterfly语法,方便遗忘时查询!

文章完善进度100%

1. 在线文件

1.1 图片

1.1.1 inlineimage标签⭐

1
{% inlineimage https://pic1.imgdb.cn/item/685a6ecb58cb8da5c86b8407.png, height=250px %}

• 图片固定靠左显示,height用于调节图片高度,它的宽度会等比例增大或缩小,如右栏图1。
• 当图片太长时,会导致只显示一部分图片,可以适当调小点height值。
• 这标签前后都可以加字,变成行内图片(此时height属性作用就不大了),如右边行内图2显示。
• 根据上面的启发,你也可以将两个标签在同一行写,就形成了一行两张图片的样式,如右图3

图1:

图2:

图3:

1.1.2 img前端标签

1
<img src="https://s3.bmp.ovh/imgs/2025/08/02/a85492c6778f7484.png" alt="示例图片" style="zoom:50%;" />

• TMD,别想那么多,没法像前端那样加属性&值,会导致博客其它地方样式变化,想像前端一样得用raw标签
• style用来调整图片大小,值越大则图片越大。
• alt为点开图片后,图片下面显示的描述信息。

1.1.3 markdown语法

1
![code](https://pic1.imgdb.cn/item/68652aff58cb8da5c88a23eb.png)

• 通用性不大,了解一下就行。

1.1.4 image标签

1
{% image https://pic1.imgdb.cn/item/68650fff58cb8da5c88969b9.png, width=400px, alt=每天下课回宿舍的路,没有什么故事。 %}

• 默认居中显示,alt的文字会直接显示在图片的下面,width用于调整图片高度。
• 删了width后,图片会正好显示“左右宽度占满div”。

1.1.5 画廊图片

画廊分类页:

1
2
3
4
<div class="gallery-group-main">
{% galleryGroup MC 在Rikkaの六花服务器里留下的足迹 '/gallery/MC/' https://cdn.cbd.int/akilar-candyassets@1.0.36/image/1.jpg %}
{% galleryGroup Gundam 哦咧哇gundam哒! '/gallery/Gundam/' https://cdn.cbd.int/akilar-candyassets@1.0.36/image/20200907110508327.png %}
</div>

画廊详细页:

1
2
3
4
{% gallery %}
![](https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg)
![](https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg)
{% endgallery %}

效果1见:画廊分类页面
效果2见:画廊详细页面

1.1.6 阿里图标 icon

1
{% icon icon-rat,2 %}

• icon-rat:表示图标font-class,可以在阿里矢量图标库项目中的font-class引用方案内查询并复制。
①搜索自己心仪的图标,然后选择添加入库,加到购物车。②选择完毕后点击右上角的购物车图标,打开侧栏,选择添加到项目,然后就会跳转到我的项目页面。③指针放到想要的图标上,点击复制代码就行!
• font-size:表示图标大小,直接填写数字即可,单位为em。图标大小默认值为1em。

1.2 音频

在线音频主要使用“audio标签”。

1
{% audio https://github.com/volantis-x/volantis-docs/releases/download/assets/Lumia1020.mp3 %}

1.3 视频

在线视频主要使用“video标签”。
类型一:1行1个视频。

1
{% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %}

类型二:1行多个视频,只需改动下面代码的数字就行。

1
2
3
4
5
6
{% videos, 4 %}
{% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %}
{% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %}
{% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %}
{% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %}
{% endvideos %}

1行1个视频

1行多个视频

1.4 PDF文件

pdf文件主要使用到的标签为“pdf”。
类型一:本地pdf,在md文件路径下创建一个同名文件夹,其内放pdf文件名为xxx.pdf的文件

1
{% pdf xxx.pdf %}

类型二:在线pdf

1
{% pdf https://cdn.jsdelivr.net/gh/Justlovesmile/CDN/pdf/小作文讲义.pdf %}

不常用,略

2. 文章排版

2.1 分栏⭐

1
2
3
4
5
6
7
8
9
{% tabs 代码块 %}
<!-- tab 代码 -->
栏1内容
<!-- endtab -->

<!-- tab 效果 -->
栏2内容
<!-- endtab -->
{% endtabs %}

• 想多搞几栏,直接复制粘贴那“3行”(tab框)就行了!

2.2 代码块⭐

1
2
3
\```shell
代码内容
\```

• 使用时要把“\”删除了!

1
2
3
4
hexo clean; hexo s
hexo clean; hexo g; hexo d
git add .; git commit -m "npm publish"; npm version patch;
git push

2.3 引用⭐

1
2
3
4
5
6
7
8
9
10
>  Java
> 二级引用演示
> MySQL
> >外键
> >
> >事务
> >
> >**行级锁**(引用内部一样可以用格式)
>
> ....

Java
二级引用演示
MySQL

外键

事务

行级锁(引用内部一样可以用格式)

….

2.4 折叠框⭐

1
2
3
{% folding green, 查看代码测试 %}
假装这里有代码块
{% endfolding %}

• 可以将green改为:“blue, cyan, green, yellow, red”等,以改变折叠框颜色;
• 不写颜色时,默认为灰白色。
green改成green open可以让折叠框默认打开。

查看代码测试

假装这里有代码块

2.5 时间轴⭐

1
2
3
4
5
6
7
8
9
10
11
12
13
{% timeline 建站历程,blue %}
<!-- timeline 2025-05-08 -->
今天是5月8日,…………
<!-- endtimeline -->

<!-- timeline 2025-05-04 -->
今天是5月4号,…………
<!-- endtimeline -->

<!-- timeline 2025-05-02 -->
今天是5月2日,…………
<!-- endtimeline -->
{% endtimeline %}

• 建站历程那标题可以删了!
• 推荐使用时间从上往下递增的样式!

建站历程

2025-05-08

今天是5月8日,…………

2025-05-14

今天是5月14号,…………

2025-05-22

今天是5月22日,…………

2.6 分割线

1
---

• 将” — “换成” *** “也是可以的!


2.7 注释 notation

1
{% nota 把鼠标移动到我上面试试 ,可以看到注解内容出现在顶栏 %}

• 把鼠标移动到“内容”上面,就会显示出“隐藏内容”!

把鼠标移动到我上面试试

2.8 隐藏块

1
2
3
{% hideBlock 点我预览, blue %}
这里有字
{% endhideBlock %}

• 点击“点我预览”按钮后,就会用“这里有字”覆盖按钮!

这里有字

3. 前端代码

3.1 空格(&nbsp)⭐

1
&nbsp;

• 可以直接在文章中写,代表空格!
• 大概要6个“&nbsp”才代码两个中文字。

3.2 回车(br)

1
</br>

• 用于换一行重新开始写,相当于回车!

3.3 raw标签

1
2
3
{% raw %}
前端代码,最好css、js与外部隔离。
{% endraw %}

下面我将记录一些本人博客建站过程的常用的前端raw代码!“轮播图、多页按钮、音乐页面、网址导航页面、我の名言页面、关于我页面、小说收藏页面”

3.3.1 轮播图

效果见本博客画廊详细页,代码如下所示:

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
{% raw %}
<!-- 自定义元素容器 -->
<image-carousel data-images='[
"https://pic1.imgdb.cn/item/68552b1658cb8da5c85e8bd3.jpg",
"https://pic1.imgdb.cn/item/68552b1658cb8da5c85e8bd6.png",
"https://pic1.imgdb.cn/item/6856232e58cb8da5c85f34d0.jpg",
"https://pic1.imgdb.cn/item/6856232e58cb8da5c85f34cf.png",
"https://pic1.imgdb.cn/item/6856232d58cb8da5c85f34cb.png",
"https://pic1.imgdb.cn/item/68567bf058cb8da5c8608c86.jpg",
"https://pic1.imgdb.cn/item/68567bde58cb8da5c8608c84.jpg"
]'></image-carousel>
<script>
// 定义自定义元素
class ImageCarousel extends HTMLElement {
constructor() {
super();
// 创建Shadow DOM
this.attachShadow({ mode: 'open' });

// 初始化图片URL数组
this.imageUrls = [];
this.index = 0;
this.time = null;
}
connectedCallback() {
// 从data-images属性获取图片URL
const imagesData = this.getAttribute('data-images');
try {
this.imageUrls = imagesData ? JSON.parse(imagesData) : this.getDefaultImages();
} catch (e) {
console.error("Invalid images data format, using default images instead");
this.imageUrls = this.getDefaultImages();
}

this.render();
this.initElements();
this.createImages();
this.createThumbnails(); // 创建缩略图
this.timer();
this.addEventListeners();
}
getDefaultImages() {
return [
"https://pic1.imgdb.cn/item/68552b1658cb8da5c85e8bd3.jpg",
"https://pic1.imgdb.cn/item/68552b1658cb8da5c85e8bd6.png",
"https://pic1.imgdb.cn/item/6856232e58cb8da5c85f34d0.jpg",
"https://pic1.imgdb.cn/item/6856232e58cb8da5c85f34cf.png",
"https://pic1.imgdb.cn/item/6856232d58cb8da5c85f34cb.png",
"https://pic1.imgdb.cn/item/68567bf058cb8da5c8608c86.jpg",
"https://pic1.imgdb.cn/item/68567bde58cb8da5c8608c84.jpg"
];
}
render() {
this.shadowRoot.innerHTML = `
<style>
* {
padding: 0px;
margin: 0px;
list-style: none;
bottom: 0;
text-decoration: none;
}
.carousel-container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.shell {
width: 870px;
height: 520px;
position: relative;
overflow: hidden;
border-radius: 5px;
border: 10px #fff solid;
}
.images {
width: ${this.imageUrls.length * 100}%;
height: 100%;
display: flex;
position: absolute;
left: 0;
transition: 0.5s;
}
.img {
width: ${100 / this.imageUrls.length}%;
background-size: cover;
background-position: center;
}
.min-images {
display: flex;
justify-content: center;
position: absolute;
bottom: 20px;
width: 100%;
z-index: 999;
}
.min {
width: 10px;
height: 10px;
margin: 0 3px;
cursor: pointer;
border-radius: 50%;
background-color: white;
border: 1px solid rgba(0, 0, 0, 0.5);
transition: all 0.3s;
}
.min.active {
background-color: transparent;
border-color: white;
}
.button {
width: 100%;
height: 100%;
position: absolute;
display: flex;
justify-content: space-between;
user-select: none;
}
.button-left,
.button-right {
font-size: 50px;
background-color: rgba(160, 193, 255, 0.7);
padding: 0 20px;
cursor: pointer;
line-height: 500px;
}

/* 缩略图样式 */
.thumbnails {
display: flex;
justify-content: center;
gap: 10px;
padding: 10px;
background-color: #f0f0f0;
border-radius: 5px;
margin-top: 10px;
width: 870px;
}

.thumbnail {
width: 80px;
height: 50px;
background-size: cover;
background-position: center;
cursor: pointer;
border: 2px solid transparent;
border-radius: 3px;
transition: all 0.3s;
}

.thumbnail.active {
border-color: #4361ee;
transform: scale(1.05);
}
</style>
<div class="carousel-container">
<div class="shell">
<ul class="images"></ul>
<ul class="min-images"></ul>
<div class="button">
<div class="button-left">&lt;</div>
<div class="button-right">&gt;</div>
</div>
</div>
<div class="thumbnails"></div> <!-- 缩略图容器 -->
</div>
`;
}
initElements() {
this.imagesContainer = this.shadowRoot.querySelector(".images");
this.minImagesContainer = this.shadowRoot.querySelector(".min-images");
this.leftButton = this.shadowRoot.querySelector(".button-left");
this.rightButton = this.shadowRoot.querySelector(".button-right");
this.thumbnailsContainer = this.shadowRoot.querySelector(".thumbnails");
}
createImages() {
// 清空容器
this.imagesContainer.innerHTML = '';
this.minImagesContainer.innerHTML = '';

this.imageUrls.forEach((url, i) => {
const img = document.createElement("li");
img.classList.add("img");
img.style.backgroundImage = `url(${url})`;
this.imagesContainer.appendChild(img);
const minImg = document.createElement("li");
minImg.classList.add("min");
if (i === 0) {
minImg.classList.add("active");
}
this.minImagesContainer.appendChild(minImg);
});
}
// 创建缩略图
createThumbnails() {
this.thumbnailsContainer.innerHTML = '';

this.imageUrls.forEach((url, i) => {
const thumbnail = document.createElement("div");
thumbnail.classList.add("thumbnail");
thumbnail.style.backgroundImage = `url(${url})`;
if (i === 0) {
thumbnail.classList.add("active");
}

thumbnail.addEventListener("click", () => {
this.index = i;
this.updateIndicators();
this.updateThumbnails();
this.position();
clearInterval(this.time);
this.timer();
});

this.thumbnailsContainer.appendChild(thumbnail);
});
}
position() {
this.imagesContainer.style.left = (this.index * -100) + "%";
}
add() {
if (this.index >= this.imageUrls.length - 1) {
this.index = 0;
} else {
this.index++;
}
this.updateIndicators();
this.updateThumbnails();
}
desc() {
if (this.index < 1) {
this.index = this.imageUrls.length - 1;
} else {
this.index--;
}
this.updateIndicators();
this.updateThumbnails();
}
updateIndicators() {
const minImages = this.minImagesContainer.querySelectorAll(".min");
minImages.forEach((minImg, i) => {
if (i === this.index) {
minImg.classList.add("active");
} else {
minImg.classList.remove("active");
}
});
}
// 更新缩略图选中状态
updateThumbnails() {
const thumbnails = this.thumbnailsContainer.querySelectorAll(".thumbnail");
thumbnails.forEach((thumbnail, i) => {
if (i === this.index) {
thumbnail.classList.add("active");
} else {
thumbnail.classList.remove("active");
}
});
}
timer() {
this.time = setInterval(() => {
this.add();
this.position();
}, 3000);
}
addEventListeners() {
this.leftButton.addEventListener("click", () => {
this.desc();
this.position();
clearInterval(this.time);
this.timer();
});
this.rightButton.addEventListener("click", () => {
this.add();
this.position();
clearInterval(this.time);
this.timer();
});
this.minImagesContainer.addEventListener("click", (event) => {
if (event.target.classList.contains("min")) {
const minImages = Array.from(this.minImagesContainer.children);
const targetIndex = minImages.indexOf(event.target);
this.index = targetIndex;
this.updateIndicators();
this.updateThumbnails();
this.position();
clearInterval(this.time);
this.timer();
}
});
}
}
// 注册自定义元素
customElements.define('image-carousel', ImageCarousel);
</script>
{% endraw %}

3.3.2 多页按钮

1
2
3
4
5
6
7
8
9
10
11
{% raw %}
<center><font font-family="ZhuZiAWan_light" size="4px">

<a class="gallery_link" href="/life/gallery/girl2/index.html" data-pjax-state=""><mark class="hl-label blue">&nbsp;<b>上一页</b>&nbsp;</mark></a> &nbsp; &nbsp;

<b>2</b> &nbsp;&nbsp;

<a class="gallery_link" href="/life/gallery/girl2/p3/index.html" data-pjax-state=""><mark class="hl-label blue">&nbsp;<b>下一页</b>&nbsp;</mark></a> &nbsp; &nbsp;

</font></center>
{% endraw %}

• 针对不同页,只需修改中间那a与b标签就行,b标签对应本页面!

3.3.3 音乐页面

效果见本博客音乐页面,代码如下所示:

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
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
{% raw %}
<!-- 这是我们的挂载点 -->
<div id="music-player-container"></div>

<script>
(function() {
// 创建隔离的作用域
const container = document.getElementById('music-player-container');

// 创建唯一的ID前缀,用于样式隔离
const uniqueId = 'music-player-' + Math.random().toString(36).substr(2, 9);

// 添加HTML结构和样式
container.innerHTML = `
<style id="${uniqueId}-styles">
/* 新增外部容器样式 - 粉蓝色主题 */
#music-player-container {
background: linear-gradient(135deg, #e6f0ff 0%, #f0f8ff 100%);
padding: 5px;
border-radius: 18px;
margin: 25px 0;
box-shadow: 0 6px 20px rgba(100, 149, 237, 0.25);
transition: all 0.3s ease;
border: 1px solid #c9ddff;
}

#music-player-container:hover {
background: linear-gradient(135deg, #d9e6ff 0%, #e6f2ff 100%);
box-shadow: 0 8px 25px rgba(100, 149, 237, 0.35);
}

#${uniqueId} {
display: block;
font-family: Arial, sans-serif;
--primary-color: #5b7cff; /* 调整为更亮的蓝色 */
--primary-hover: #4a6bf5;
--active-color: #ff6b8b; /* 改为粉色增加对比 */
--text-color: #333;
--light-gray: #f5f9ff; /* 更蓝的浅灰色 */
--medium-gray: #e0e8ff; /* 带蓝色调的灰色 */
--dark-gray: #6a7a9b; /* 蓝灰色 */
--white: #f8fbff; /* 浅粉蓝白色 */
}

#${uniqueId} #music-player {
background-color: var(--white);
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
padding: 30px;
width: 100%;
max-width: 1000px;
margin: 0 auto;
box-sizing: border-box;
border: 1px solid #d4e3ff;
background-image:
radial-gradient(circle at 10% 20%, rgba(255,255,255,0.8) 0%, transparent 20%),
radial-gradient(circle at 90% 80%, rgba(230,240,255,0.6) 0%, transparent 20%);
}

/* 其余原有样式保持不变... */
#${uniqueId} .player-header {
text-align: center;
margin-bottom: 20px;
color: var(--text-color);
}

#${uniqueId} .folder-input-container {
text-align: center;
margin-bottom: 20px;
}

#${uniqueId} .folder-input-label {
display: inline-block;
background-color: var(--primary-color);
color: var(--white);
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}

#${uniqueId} .folder-input-label:hover {
background-color: var(--primary-hover);
}

#${uniqueId} input[type="file"] {
display: none;
}

#${uniqueId} .player-controls {
display: flex;
justify-content: center;
gap: 20px;
margin: 20px 0;
}

#${uniqueId} .control-btn, #${uniqueId} .mode-btn {
background-color: var(--primary-color);
color: var(--white);
border: none;
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s;
}

#${uniqueId} .control-btn:hover, #${uniqueId} .mode-btn:hover {
background-color: var(--primary-hover);
}

#${uniqueId} .mode-btn {
border-radius: 20px;
width: auto;
padding: 0 15px;
}

#${uniqueId} .mode-btn.active {
background-color: var(--active-color);
}

#${uniqueId} .progress-container {
height: 5px;
background-color: var(--medium-gray);
border-radius: 5px;
margin: 20px 0;
cursor: pointer;
}

#${uniqueId} .progress-bar {
height: 100%;
background-color: var(--primary-color);
border-radius: 5px;
width: 0%;
transition: width 0.1s linear;
}

#${uniqueId} .time-display {
display: flex;
justify-content: space-between;
font-size: 14px;
color: var(--dark-gray);
margin-bottom: 20px;
}

#${uniqueId} .volume-control {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 20px;
color: var(--text-color);
}

/* 自定义音量条样式 */
#${uniqueId} .custom-volume-container {
position: relative;
height: 5px;
background-color: #e0e0e0; /* 灰色背景 */
border-radius: 5px;
flex: 1;
cursor: pointer;
}

#${uniqueId} .custom-volume-bar {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: var(--primary-color); /* 蓝色填充 */
border-radius: 5px;
width: 30%; /* 默认音量30% */
transition: width 0.1s linear;
}

#${uniqueId} .custom-volume-handle {
position: absolute;
top: 50%;
left: 30%; /* 默认音量30% */
transform: translate(-50%, -50%);
width: 14px;
height: 14px;
background-color: white;
border-radius: 50%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
transition: left 0.1s linear;
z-index: 1;
}

#${uniqueId} input[type="range"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
z-index: 2;
}

#${uniqueId} .playlist {
max-height: 300px;
overflow-y: auto;
border-top: 1px solid var(--medium-gray);
padding-top: 15px;
}

#${uniqueId} .playlist-item {
display: flex;
align-items: center;
padding: 10px;
border-bottom: 1px solid var(--medium-gray);
cursor: pointer;
transition: background-color 0.2s;
color: var(--text-color);
white-space: nowrap;
}

#${uniqueId} .playlist-item:hover {
background-color: var(--light-gray);
}

#${uniqueId} .playlist-item.active {
background-color: rgba(91, 124, 255, 0.1);
}

#${uniqueId} .playlist-item.active .name {
color: var(--primary-color) !important;
font-weight: bold;
}

#${uniqueId} .index {
width: 25px;
text-align: center;
color: var(--dark-gray);
margin-right: 10px;
flex-shrink: 0;
}

#${uniqueId} .name {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

#${uniqueId} .empty-state {
text-align: center;
color: var(--dark-gray);
padding: 20px;
}

#${uniqueId} #loading-indicator {
display: none;
text-align: center;
padding: 20px;
margin: 20px 0;
background: rgba(240, 244, 255, 0.8);
border-radius: 10px;
border: 1px solid #d0d8e8;
}

#${uniqueId} .spinner {
width: 40px;
height: 40px;
margin: 0 auto 15px;
border: 4px solid rgba(91, 124, 255, 0.3);
border-radius: 50%;
border-top-color: var(--primary-color);
animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
to { transform: rotate(360deg); }
}

#${uniqueId} .progress-text {
margin-top: 10px;
color: var(--primary-color);
font-size: 14px;
}

#${uniqueId} .upload-progress-container {
height: 10px;
background-color: var(--medium-gray);
border-radius: 5px;
margin-top: 15px;
overflow: hidden;
}

#${uniqueId} .upload-progress-bar {
height: 100%;
background-color: var(--primary-color);
width: 0%;
transition: width 0.3s ease;
}

@media (max-width: 500px) {
#music-player-container {
padding: 15px;
margin: 15px 0;
}

#${uniqueId} #music-player {
padding: 20px;
}

#${uniqueId} .player-controls {
gap: 10px;
}

#${uniqueId} .control-btn, #${uniqueId} .mode-btn {
width: 35px;
height: 35px;
font-size: 14px;
}

#${uniqueId} .mode-btn {
padding: 0 10px;
}
}
</style>
<div id="${uniqueId}">
<div id="music-player">
<div class="player-header">
<p id="status-text">请选择包含音乐的文件夹</p>
</div>

<div class="folder-input-container">
<label for="folder-input" class="folder-input-label">
📁 选择音乐文件夹
</label>
<input type="file" id="folder-input" webkitdirectory directory multiple>
</div>

<div id="loading-indicator">
<div class="spinner"></div>
<p>正在加载音乐文件,请稍候...</p>
<div class="upload-progress-container">
<div class="upload-progress-bar" id="upload-progress-bar"></div>
</div>
<div class="progress-text" id="progress-text">0/0 文件已处理</div>
</div>

<div class="player-controls">
<button class="control-btn" id="prev-btn" disabled title="上一首">⏮</button>
<button class="control-btn" id="play-btn" title="播放">▶</button>
<button class="control-btn" id="next-btn" disabled title="下一首">⏭</button>
<button class="mode-btn active" id="shuffle-btn" title="随机播放">🔀 随机</button>
<button class="mode-btn" id="sequential-btn" title="顺序播放">⏩ 顺序</button>
</div>

<div class="progress-container" id="progress-container">
<div class="progress-bar" id="progress-bar"></div>
</div>

<div class="time-display">
<span id="current-time">0:00</span>
<span id="duration">0:00</span>
</div>

<div class="volume-control">
<span>音量:</span>
<div class="custom-volume-container">
<div class="custom-volume-bar" id="custom-volume-bar"></div>
<div class="custom-volume-handle" id="custom-volume-handle"></div>
<input type="range" id="volume" min="0" max="1" step="0.01" value="0.3">
</div>
<span id="volume-percentage">30%</span>
</div>

<div class="playlist" id="playlist">
<div class="empty-state">暂无音乐,请选择文件夹</div>
</div>
</div>
</div>
`;

// 获取元素时加上唯一ID前缀
const getElement = (id) => document.querySelector(`#${uniqueId} #${id}`);

const audio = new Audio();
let currentTrackIndex = 0;
let tracks = [];
let isPlaying = false;
let isShuffleMode = true;
let originalOrder = [];
let currentFileURLs = new Set();

// 获取元素
const playBtn = getElement('play-btn');
const prevBtn = getElement('prev-btn');
const nextBtn = getElement('next-btn');
const shuffleBtn = getElement('shuffle-btn');
const sequentialBtn = getElement('sequential-btn');
const progressContainer = getElement('progress-container');
const progressBar = getElement('progress-bar');
const currentTimeEl = getElement('current-time');
const durationEl = getElement('duration');
const volumeControl = getElement('volume');
const playlistEl = getElement('playlist');
const folderInput = getElement('folder-input');
const statusText = getElement('status-text');
const loadingIndicator = getElement('loading-indicator');
const progressText = getElement('progress-text');
const uploadProgressBar = getElement('upload-progress-bar');
const volumePercentage = getElement('volume-percentage');

// 新增的自定义音量条元素
const customVolumeBar = getElement('custom-volume-bar');
const customVolumeHandle = getElement('custom-volume-handle');
const customVolumeContainer = customVolumeBar.parentElement;

// 加载音乐文件夹
folderInput.addEventListener('change', async function (e) {
cleanupFileURLs();

const files = Array.from(e.target.files).filter(file =>
file.type.startsWith('audio/')
);

if (files.length === 0) {
statusText.textContent = "文件夹中没有找到音乐文件";
return;
}

loadingIndicator.style.display = 'block';
statusText.textContent = `正在加载 ${files.length} 首音乐...`;
uploadProgressBar.style.width = '0%';
progressText.textContent = '准备中...';

try {
tracks = await processFilesWithProgress(files);
originalOrder = [...tracks];
renderPlaylist();
loadTrack(currentTrackIndex);
updateButtons();
statusText.textContent = `已加载 ${tracks.length} 首音乐,准备播放`;
} catch (error) {
console.error("加载音乐失败:", error);
statusText.textContent = "加载音乐时出错: " + error.message;
} finally {
loadingIndicator.style.display = 'none';
}
});

// 带进度反馈的文件处理函数
async function processFilesWithProgress(files) {
return new Promise((resolve, reject) => {
const results = [];
const total = files.length;
let processed = 0;
let failed = 0;

const processNextBatch = (index) => {
if (index >= total) {
if (processed === 0 && failed > 0) {
reject(new Error("无法处理任何音乐文件"));
} else {
resolve(results);
}
return;
}

const batchSize = 5;
const endIndex = Math.min(index + batchSize, total);

for (let i = index; i < endIndex; i++) {
const file = files[i];

if (currentFileURLs.has(file.name)) {
console.warn(`跳过重复文件: ${file.name}`);
processed++;
continue;
}

try {
const fileURL = URL.createObjectURL(file);
currentFileURLs.add(file.name);

results.push({
index: results.length + 1,
name: file.name.replace(/\.[^/.]+$/, ""),
path: fileURL,
file: file
});
processed++;
} catch (error) {
console.error(`处理文件 ${file.name} 失败:`, error);
failed++;
}
}

const percent = Math.round((processed / total) * 100);
uploadProgressBar.style.width = `${percent}%`;
progressText.textContent = `${processed}/${total} 文件已处理${failed > 0 ? ` (${failed} 个失败)` : ''}`;

setTimeout(() => processNextBatch(endIndex), 10);
};

processNextBatch(0);
});
}

// 清理所有已创建的文件URL
function cleanupFileURLs() {
if (audio.src && audio.src.startsWith('blob:')) {
URL.revokeObjectURL(audio.src);
}

currentFileURLs.forEach(url => {
try {
URL.revokeObjectURL(url);
} catch (error) {
console.error("释放URL失败:", error);
}
});

currentFileURLs.clear();
}

// 渲染播放列表
function renderPlaylist() {
if (tracks.length === 0) {
playlistEl.innerHTML = '<div class="empty-state">暂无音乐,请选择文件夹</div>';
return;
}

playlistEl.innerHTML = '';
tracks.forEach((track, index) => {
const item = document.createElement('div');
item.className = `playlist-item ${index === currentTrackIndex ? 'active' : ''}`;
item.innerHTML = `
<span class="index">${index + 1}</span>
<span class="name">${track.name}</span>
`;
item.addEventListener('click', () => {
currentTrackIndex = index;
loadTrack(currentTrackIndex);
playTrack();
});
playlistEl.appendChild(item);
});

// 自动滚动到当前选中的音乐
scrollToActiveTrack();
}

// 自动滚动到当前选中的音乐
function scrollToActiveTrack() {
const activeItem = playlistEl.querySelector('.playlist-item.active');
if (activeItem) {
activeItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}

// 加载曲目
function loadTrack(index) {
if (tracks.length === 0) return;

const track = tracks[index];

if (audio.src && audio.src.startsWith('blob:')) {
URL.revokeObjectURL(audio.src);
}

audio.src = track.path;
audio.volume = 0.3;
audio.load();

statusText.textContent = `正在播放: ${track.name} (${index + 1}/${tracks.length})`;
renderPlaylist();
updateVolumePercentage(0.3);
}

// 播放曲目
function playTrack() {
if (tracks.length === 0) return;

audio.play()
.then(() => {
isPlaying = true;
playBtn.textContent = '⏸';
playBtn.title = "暂停";
})
.catch(error => {
console.error("播放失败:", error);
statusText.textContent = `播放失败: ${error.message}`;
});
}

// 暂停曲目
function pauseTrack() {
audio.pause();
isPlaying = false;
playBtn.textContent = '▶';
playBtn.title = "播放";
}

// 下一首
function nextTrack() {
if (tracks.length === 0) return;

if (isShuffleMode) {
currentTrackIndex = Math.floor(Math.random() * tracks.length);
} else {
currentTrackIndex = (currentTrackIndex + 1) % tracks.length;
}

loadTrack(currentTrackIndex);
playTrack();
}

// 上一首
function prevTrack() {
if (tracks.length === 0) return;

if (isShuffleMode) {
currentTrackIndex = Math.floor(Math.random() * tracks.length);
} else {
currentTrackIndex = (currentTrackIndex - 1 + tracks.length) % tracks.length;
}

loadTrack(currentTrackIndex);
playTrack();
}

// 切换随机播放模式
function toggleShuffleMode() {
isShuffleMode = true;
shuffleBtn.classList.add('active');
sequentialBtn.classList.remove('active');
}

// 切换顺序播放模式
function toggleSequentialMode() {
isShuffleMode = false;
sequentialBtn.classList.add('active');
shuffleBtn.classList.remove('active');
}

// 更新按钮状态
function updateButtons() {
const hasTracks = tracks.length > 0;
prevBtn.disabled = !hasTracks || tracks.length <= 1;
nextBtn.disabled = !hasTracks || tracks.length <= 1;

if (hasTracks) {
playBtn.disabled = false;
}
}

// 播放/暂停按钮点击事件
playBtn.addEventListener('click', () => {
if (tracks.length === 0) {
folderInput.click();
return;
}

if (isPlaying) {
pauseTrack();
} else {
playTrack();
}
});

// 注册其他按钮事件
nextBtn.addEventListener('click', nextTrack);
prevBtn.addEventListener('click', prevTrack);
shuffleBtn.addEventListener('click', toggleShuffleMode);
sequentialBtn.addEventListener('click', toggleSequentialMode);

// 音频时间更新事件
audio.addEventListener('timeupdate', function() {
if (isNaN(audio.duration)) return;

const progressPercent = (audio.currentTime / audio.duration) * 100;
progressBar.style.width = `${progressPercent}%`;

currentTimeEl.textContent = formatTime(audio.currentTime);
durationEl.textContent = formatTime(audio.duration);
});

// 格式化时间显示
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}

// 进度条点击事件
progressContainer.addEventListener('click', (e) => {
if (isNaN(audio.duration)) return;

const width = progressContainer.clientWidth;
const clickX = e.offsetX;
const duration = audio.duration;

audio.currentTime = (clickX / width) * duration;
});

// 音量控制
volumeControl.addEventListener('input', (e) => {
const volume = parseFloat(e.target.value);
audio.volume = volume;
updateVolumePercentage(volume);
updateCustomVolumeBar(volume);
});

// 自定义音量条点击事件
customVolumeContainer.addEventListener('click', (e) => {
const rect = customVolumeContainer.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const width = rect.width;
const volume = Math.max(0, Math.min(1, clickX / width));

volumeControl.value = volume;
audio.volume = volume;
updateVolumePercentage(volume);
updateCustomVolumeBar(volume);
});

// 更新自定义音量条显示
function updateCustomVolumeBar(volume) {
const percentage = volume * 100;
customVolumeBar.style.width = `${percentage}%`;
customVolumeHandle.style.left = `${percentage}%`;
}

// 更新音量百分比显示
function updateVolumePercentage(volume) {
const percentage = Math.round(volume * 100);
volumePercentage.textContent = `${percentage}%`;
}

// 音频播放结束事件
audio.addEventListener('ended', nextTrack);

// 初始化音量和显示
updateVolumePercentage(0.3);
updateCustomVolumeBar(0.3);
audio.volume = 0.3;

// 默认随机播放
toggleShuffleMode();

// 页面卸载时清理资源
window.addEventListener('beforeunload', cleanupFileURLs);
})();
</script>
{% endraw %}

3.3.4 网址导航页面

效果见本博客网址导航页面,代码如下所示:

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

{% raw %}
<!-- 这是我们的挂载点 -->
<div id="nav-container"></div>
<script>
(function() {
// 创建 Shadow DOM 实现完全隔离
const container = document.getElementById('nav-container');
const shadowRoot = container.attachShadow({ mode: 'closed' });

// 创建唯一的ID前缀,用于样式隔离
const uniqueId = 'frontend-nav-' + Math.random().toString(36).substr(2, 9);

// 添加HTML结构和样式
shadowRoot.innerHTML = `
<style>
:host {
--primary-color: #6366f1;
--primary-hover: #4f46e5;
--text-color: #2d3748;
--text-secondary: #4a5568;
--bg-color: #ffffff;
--card-bg: #ffffff;
--border-radius: 8px;
--transition: all 0.2s ease;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.1);
--shadow-md: 0 3px 4px rgba(0,0,0,0.1);
--shadow-lg: 0 8px 20px rgba(0,0,0,0.1);
display: block;
margin: 0;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
all: initial; /* 重置所有继承样式 */
}

#${uniqueId} {
all: initial; /* 确保不继承外部样式 */
}

#${uniqueId} .container {
padding: 1.2rem;
background: var(--bg-color);
border-radius: var(--border-radius);
box-shadow: var(--shadow-lg);
}

#${uniqueId} header {
text-align: center;
margin-bottom: 1.2rem;
}

#${uniqueId} h1 {
font-size: 1.8rem;
margin: 0 0 0.3rem;
color: var(--text-color);
font-weight: 700;
background: linear-gradient(90deg, #6366f1, #8b5cf6);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

#${uniqueId} .subtitle {
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 1rem;
font-weight: 400;
}

#${uniqueId} .search-box {
max-width: 500px;
margin: 0 auto 1.2rem;
position: relative;
}

#${uniqueId} .search-box input {
width: 100%;
padding: 0.6rem 1.2rem;
border: 1px solid #e2e8f0;
border-radius: 40px;
font-size: 0.9rem;
outline: none;
box-shadow: var(--shadow-sm);
transition: var(--transition);
background-color: #f8fafc;
}

#${uniqueId} .search-box input:focus {
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
}

#${uniqueId} .search-box::after {
content: "🔍";
position: absolute;
right: 1.2rem;
top: 50%;
transform: translateY(-50%);
opacity: 0.5;
}

#${uniqueId} .category {
margin-bottom: 1.5rem;
}

#${uniqueId} .category-header {
display: flex;
align-items: center;
margin: 0 0 0.8rem;
padding-bottom: 0.4rem;
border-bottom: 1px solid #f1f5f9;
}

#${uniqueId} .category-icon {
font-size: 1.3rem;
margin-right: 0.6rem;
width: 1.5rem;
text-align: center;
}

#${uniqueId} .category-title {
font-size: 1.1rem;
margin: 0;
color: var(--text-color);
font-weight: 600;
flex-grow: 1;
}

#${uniqueId} .links-container {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 0.8rem;
}

#${uniqueId} .link-card {
background: var(--card-bg);
border-radius: var(--border-radius);
padding: 0.7rem;
box-shadow: var(--shadow-sm);
transition: var(--transition);
border: 1px solid #e2e8f0;
position: relative;
overflow: hidden;
}

#${uniqueId} .link-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 2px;
height: 100%;
background: linear-gradient(to bottom, var(--primary-color), #8b5cf6);
opacity: 0;
transition: var(--transition);
}

#${uniqueId} .link-card::after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 2px;
height: 100%;
background: linear-gradient(to bottom, var(--primary-color), #8b5cf6);
opacity: 0;
transition: var(--transition);
}

#${uniqueId} .link-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md);
border-color: #cbd5e0;
background-color: #f8fafc;
}

#${uniqueId} .link-card:hover::before,
#${uniqueId} .link-card:hover::after {
opacity: 1;
}

#${uniqueId} .link-card a {
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}

#${uniqueId} .link-icon {
width: 32px;
height: 32px;
margin-bottom: 0.5rem;
border-radius: 6px;
object-fit: cover;
background: #f1f5f9;
padding: 0.2rem;
box-shadow: var(--shadow-sm);
}

#${uniqueId} .link-title {
font-size: 0.9rem;
margin: 0;
color: var(--text-color);
font-weight: 600;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}

#${uniqueId} .link-description {
font-size: 0.75rem;
color: var(--text-secondary);
line-height: 1.2;
margin-top: 0.3rem;
text-align: center;
max-height: 2.4em;
overflow: hidden;
}

#${uniqueId} footer {
text-align: center;
margin-top: 1.5rem;
padding: 0.8rem;
color: var(--text-secondary);
font-size: 0.8rem;
border-top: 1px solid #f1f5f9;
}

#${uniqueId} .no-results {
grid-column: 1 / -1;
text-align: center;
padding: 1rem;
color: var(--text-secondary);
font-size: 0.9rem;
}

@media (max-width: 1200px) {
#${uniqueId} .links-container {
grid-template-columns: repeat(5, 1fr);
}
}

@media (max-width: 992px) {
#${uniqueId} .links-container {
grid-template-columns: repeat(4, 1fr);
}
}

@media (max-width: 768px) {
#${uniqueId} .links-container {
grid-template-columns: repeat(3, 1fr);
}
}

@media (max-width: 576px) {
#${uniqueId} .links-container {
grid-template-columns: repeat(2, 1fr);
}

#${uniqueId} h1 {
font-size: 1.5rem;
}

#${uniqueId} .category-title {
font-size: 1rem;
}

#${uniqueId} .search-box input {
padding: 0.5rem 1rem;
font-size: 0.85rem;
}
}
</style>
<div id="${uniqueId}">
<div class="container">
<header>
<div class="search-box">
<input type="text" placeholder="搜索框架、工具或资源..." id="search-input">
</div>
</header>
<!-- 分类内容将通过JavaScript动态生成 -->
</div>
</div>
`;
// 获取导航数据
function getNavData() {
return {
categories: [
{
title: "综合平台",
icon: "🏆",
links: [
{
name: "bilibili",
url: "https://www.bilibili.com/?spm_id_from=333.337.0.0",
icon: "https://pic1.imgdb.cn/item/68233dc758cb8da5c8f09fc4.webp",
description: "来哔哩哔哩,学习也要干杯?"
},
{
name: "CSDN",
url: "https://www.csdn.net/",
icon: "https://g.csdnimg.cn/static/logo/favicon32.ico",
description: "开发者技术社区"
},
]
},
{
title: "娱乐网站",
icon: "🎮",
links: [
{
name: "PRTS",
url: "https://prts.wiki/w/%E9%A6%96%E9%A1%B5",
icon: "https://prts.wiki/ioslogo.png",
description: "明日方舟辅助网站"
},
{
name: "星尘幻梦",
url: "https://re.xcdream.com/",
icon: "https://dl.xcdream.com/2025/01/20250106043320606.png",
description: "Window文件夹、桌面、指针美化"
},
]
},
{
title: "朋友图",
icon: "👤",
links: [
{
name: "安知鱼`Blog",
url: "https://blog.anheyu.com/",
icon: "https://npm.elemecdn.com/anzhiyu-blog-static@1.0.4/img/avatar.jpg",
description: "生活明朗,万物可爱"
},
]
}
]
};
}
// 渲染导航内容
function renderNav() {
const navData = getNavData();
const navElement = shadowRoot.querySelector(`#${uniqueId} .container`);

let html = '';
navData.categories.forEach(category => {
html += `
<div class="category" data-category="${category.title.toLowerCase().replace(/\s+/g, '-')}">
<div class="category-header">
<span class="category-icon">${category.icon}</span>
<h2 class="category-title">${category.title}</h2>
</div>
<div class="links-container">
`;

category.links.forEach(link => {
html += `
<div class="link-card" data-name="${link.name.toLowerCase()}">
<a href="${link.url}" target="_blank" rel="noopener noreferrer">
${link.icon ? `<img src="${link.icon}" alt="${link.name}" class="link-icon">` : ''}
<h3 class="link-title">${link.name}</h3>
${link.description ? `<p class="link-description">${link.description}</p>` : ''}
</a>
</div>
`;
});

html += `
</div>
</div>
`;
});

html += `
<footer>
<p>© ${new Date().getFullYear()} 前端开发者导航 | 持续更新优质前端资源</p>
</footer>
`;

navElement.innerHTML += html;
}
// 设置搜索功能
function setupSearch() {
const searchInput = shadowRoot.querySelector(`#${uniqueId} #search-input`);
const linkCards = shadowRoot.querySelectorAll(`#${uniqueId} .link-card`);
const categories = shadowRoot.querySelectorAll(`#${uniqueId} .category`);

searchInput.addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase().trim();

if (!searchTerm) {
// 恢复所有显示
linkCards.forEach(card => card.style.display = 'block');
categories.forEach(cat => {
cat.style.display = 'block';
cat.querySelector('.category-header').style.display = 'flex';
});
updateNoResultsMessage(true);
return;
}

let hasResults = false;

categories.forEach(category => {
const cards = category.querySelectorAll('.link-card');
let categoryHasResults = false;

cards.forEach(card => {
const name = card.dataset.name;
const description = card.querySelector('.link-description')?.textContent.toLowerCase() || '';

// 搜索名称或描述
if (name.includes(searchTerm) ||
description.includes(searchTerm)) {
card.style.display = 'block';
categoryHasResults = true;
} else {
card.style.display = 'none';
}
});

if (categoryHasResults) {
// 显示分类标题
category.querySelector('.category-header').style.display = 'flex';
category.style.display = 'block';
hasResults = true;
} else {
category.style.display = 'none';
}
});

updateNoResultsMessage(hasResults);
});
}
// 更新无结果消息
function updateNoResultsMessage(hasResults) {
let noResults = shadowRoot.querySelector(`#${uniqueId} .no-results`);

if (!hasResults) {
if (!noResults) {
noResults = document.createElement('div');
noResults.className = 'no-results';
noResults.textContent = '没有找到匹配的资源,请尝试其他关键词';
shadowRoot.querySelector(`#${uniqueId} .container`).appendChild(noResults);
}
} else if (noResults) {
noResults.remove();
}
}
// 初始化导航
renderNav();
setupSearch();
})();
</script>
{% endraw %}

3.3.5 我の名言页面

效果见本博客我の名言页面,代码如下所示:

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
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
{% raw %}
<!-- 这是我们的挂载点 -->
<div id="quotes-container"></div>
<script>
(function() {
// 创建隔离的作用域
const container = document.getElementById('quotes-container');

// 创建唯一的ID前缀,用于样式隔离
const uniqueId = 'quotes-' + Math.random().toString(36).substr(2, 9);

// 添加HTML结构和样式
container.innerHTML = `
<style id="${uniqueId}-styles">
/* 新增外部容器样式 - 浅绿色主题 */
#quotes-container {
background: linear-gradient(135deg, #f0fff4 0%, #f8fffa 100%);
padding: 5px;
border-radius: 18px;
margin: 25px 0;
box-shadow: 0 6px 20px rgba(100, 237, 149, 0.25);
transition: all 0.3s ease;
border: 1px solid #c9ffdd;
}
#quotes-container:hover {
background: linear-gradient(135deg, #e6ffed 0%, #f0fff4 100%);
box-shadow: 0 8px 25px rgba(100, 237, 149, 0.35);
}

#${uniqueId} {
display: block;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--primary: #48bb78; /* 绿色主题 */
--secondary: #4299e1;
--neutral-100: #f0fff4;
--neutral-200: #e2e8f0;
--neutral-800: #2d3748;
--neutral-900: #1a202c;
--red-500: #f56565;
}

#${uniqueId} .container {
max-width: 56rem;
margin: 0 auto;
padding: 30px;
background-color: white;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
border: 1px solid #e2e8f0;
}

/* 卡片样式 */
#${uniqueId} .card {
background: white;
border-radius: 0.75rem;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.03);
padding: 1.5rem;
margin-bottom: 2rem;
position: relative;
transition: all 0.3s ease;
border: 1px solid #edf2f7;
}

#${uniqueId} .card:hover {
transform: scale(1.01);
box-shadow: 0 15px 30px -5px rgba(0, 0, 0, 0.1), 0 10px 15px -6px rgba(0, 0, 0, 0.05);
}

#${uniqueId} .quote-icon {
font-size: 1.5rem;
color: rgba(72, 187, 120, 0.2);
margin-right: 1rem;
margin-top: 0.25rem;
}

#${uniqueId} .quote-text {
font-size: 1.25rem;
line-height: 1.75;
color: var(--neutral-800);
font-weight: 500;
margin-bottom: 1rem;
transition: all 0.5s ease;
}

#${uniqueId} .quote-author {
color: var(--neutral-800);
font-weight: 300;
font-style: italic;
transition: all 0.5s ease;
opacity: 0.8;
}

/* 按钮样式 */
#${uniqueId} .btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem 1rem;
border-radius: 9999px;
transition: all 0.2s ease;
cursor: pointer;
}

#${uniqueId} .like-btn {
color: #a0aec0;
background: none;
border: none;
padding: 0;
}

#${uniqueId} .like-btn:hover {
color: var(--red-500);
}

#${uniqueId} .refresh-btn {
position: absolute;
bottom: 1rem;
right: 1rem;
padding: 0.5rem;
border-radius: 9999px;
background-color: rgba(72, 187, 120, 0.1);
color: var(--primary);
border: none;
}

#${uniqueId} .refresh-btn:hover {
background-color: var(--primary);
color: white;
}

#${uniqueId} .category-btn {
background: white;
color: var(--neutral-800);
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
border: 1px solid var(--neutral-200);
padding: 0.5rem 1rem;
border-radius: 0.375rem;
transition: all 0.2s ease;
}

#${uniqueId} .category-btn:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
background-color: var(--primary);
color: white;
transform: translateY(-2px);
}

#${uniqueId} .category-btn.active {
background-color: var(--primary);
color: white;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}

/* 列表样式 */
#${uniqueId} .quotes-list {
display: flex;
flex-direction: column;
gap: 1rem;
}

#${uniqueId} .quote-item {
background: white;
padding: 1rem;
border-radius: 0.5rem;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
border: 1px solid #edf2f7;
}

#${uniqueId} .quote-item:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
transform: translateY(-0.25rem);
}

#${uniqueId} .quote-tag {
font-size: 0.75rem;
color: var(--primary);
background-color: rgba(72, 187, 120, 0.1);
padding: 0.25rem 0.5rem;
border-radius: 9999px;
margin-right: 0.25rem;
}

/* 分页样式 */
#${uniqueId} .pagination {
display: flex;
justify-content: center;
margin-top: 2rem;
gap: 0.5rem;
}

#${uniqueId} .page-btn {
padding: 0.5rem 1rem;
border: 1px solid var(--neutral-200);
background: white;
border-radius: 0.375rem;
cursor: pointer;
transition: all 0.2s ease;
}

#${uniqueId} .page-btn:hover {
background-color: var(--neutral-100);
}

#${uniqueId} .page-btn.active {
background-color: var(--primary);
color: white;
border-color: var(--primary);
}

#${uniqueId} .page-btn.disabled {
opacity: 0.5;
cursor: not-allowed;
}

/* 动画 */
@keyframes pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}

#${uniqueId} .animate-pulse {
animation: pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* 工具类 */
#${uniqueId} .flex {
display: flex;
}

#${uniqueId} .items-start {
align-items: flex-start;
}

#${uniqueId} .justify-between {
justify-content: space-between;
}

#${uniqueId} .items-center {
align-items: center;
}

#${uniqueId} .flex-wrap {
flex-wrap: wrap;
}

#${uniqueId} .gap-2 {
gap: 0.5rem;
}

#${uniqueId} .mb-4 {
margin-bottom: 1rem;
}

#${uniqueId} .mb-8 {
margin-bottom: 2rem;
}

#${uniqueId} .mr-4 {
margin-right: 1rem;
}

#${uniqueId} .mt-1 {
margin-top: 0.25rem;
}

#${uniqueId} .text-lg {
font-size: 1.125rem;
}

#${uniqueId} .font-medium {
font-weight: 500;
}

#${uniqueId} .text-neutral-800 {
color: var(--neutral-800);
}

#${uniqueId} .text-neutral-600 {
color: var(--neutral-600);
}

#${uniqueId} .text-sm {
font-size: 0.875rem;
}

#${uniqueId} .italic {
font-style: italic;
}

#${uniqueId} .text-xl {
font-size: 1.5rem; /* 20px */
line-height: 1.75rem; /* 28px */
}
#${uniqueId} .quote-item {
background: white;
padding: 1.25rem;
border-radius: 0.75rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
border: 2px solid #edf2f7;
margin-bottom: 1rem;
}

#${uniqueId} .quote-item:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
border-color: var(--primary);
}

#${uniqueId} .quote-item p {
font-size: 1.1rem;
line-height: 1.8;
color: var(--neutral-800);
margin-bottom: 0.75rem;
}

#${uniqueId} .quote-item .text-neutral-600 {
font-size: 0.95rem;
color: var(--neutral-800);
opacity: 0.9;
}

#${uniqueId} .quote-tag {
font-size: 0.8rem;
font-weight: 500;
color: var(--primary);
background-color: rgba(72, 187, 120, 0.15);
padding: 0.3rem 0.7rem;
border-radius: 1rem;
margin-right: 0.5rem;
transition: all 0.2s ease;
}

#${uniqueId} .quote-item:hover .quote-tag {
background-color: rgba(72, 187, 120, 0.25);
}

#${uniqueId} .font-bold {
font-weight: 700;
}
#${uniqueId} .leading-relaxed {
line-height: 1.625;
}
#${uniqueId} .card {
background: white;
border-radius: 0.75rem;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
padding: 1.75rem;
margin-bottom: 2.5rem;
position: relative;
transition: all 0.3s ease;
border: 2px solid #edf2f7;
}

#${uniqueId} .card:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
border-color: var(--primary);
}

#${uniqueId} .quote-text {
font-size: 1.3rem;
line-height: 1.8;
color: var(--neutral-900);
font-weight: 500;
margin-bottom: 1.25rem;
transition: all 0.5s ease;
}

#${uniqueId} .quote-author {
font-size: 1.05rem;
color: var(--neutral-800);
font-weight: 400;
font-style: italic;
transition: all 0.5s ease;
}

#${uniqueId} .refresh-btn {
position: absolute;
bottom: 1.25rem;
right: 1.25rem;
padding: 0.6rem;
border-radius: 9999px;
background-color: rgba(72, 187, 120, 0.15);
color: var(--primary);
border: none;
transition: all 0.2s ease;
}

#${uniqueId} .refresh-btn:hover {
background-color: var(--primary);
color: white;
transform: rotate(90deg);
}
@media (max-width: 500px) {
#quotes-container {
padding: 15px;
margin: 15px 0;
}

#${uniqueId} .container {
padding: 20px;
}

#${uniqueId} .quote-text {
font-size: 1rem;
}

#${uniqueId} .card {
padding: 1rem;
}
}
</style>
<div id="${uniqueId}">
<div class="container">
<!-- 名言卡片 -->
<div id="quote-card" class="card">
<div class="flex items-start">
<i class="fa fa-quote-left quote-icon"></i>
<div>
<p id="quote-text" class="quote-text">
知不足而奋进,望远山而前行!
</p>
<div class="flex justify-between items-center">
<p id="quote-author" class="quote-author">
—— 孙伟
</p>
<button id="like-btn" class="like-btn">
<i class="fa fa-heart-o"></i>
</button>
</div>
</div>
</div>
<!-- 随机名言按钮 -->
<button id="refresh-btn" class="refresh-btn">
<i class="fa fa-refresh"></i>
</button>
</div>
<!-- 分类标签 -->
<div class="mb-8">
<p class="text-xl font-bold text-neutral-800 mb-4">名言分类</p>
<div class="flex flex-wrap gap-2" id="category-container">
<button class="category-btn active">
全部
</button>
</div>
</div>
<!-- 名言列表 -->
<div>
<div id="quotes-list" class="quotes-list">
<!-- 名言项将通过JavaScript动态生成 -->
</div>
<!-- 分页导航 -->
<div id="pagination" class="pagination">
<!-- 分页按钮将通过JavaScript动态生成 -->
</div>
</div>
</div>
</div>
`;
// 获取元素时加上唯一ID前缀
const getElement = (id) => document.querySelector(`#${uniqueId} #${id}`);

// 名言数据
const quotes = [
{
text: "你全力做到的最好,可能还不如别人的随便搞搞。",
author: "网友",
categories: ["毒鸡汤"]
},
{
text: "懒是一个很好的托辞,说得好像勤快了,就真能干出什么大事儿一样。",
author: "网友",
categories: ["毒鸡汤"]
},
{
text: "总有这样的人,该干活的时候职业不起来,玩的时候又放不开。",
author: "北大学长",
categories: ["学习方法"]
},
{
text: "在发现我没有道德后,对方放弃了道德绑架。",
author: "b站",
categories: ["格局"]
},
{
text: "等生活中真有了生老病死这样的大事,才知道自己以前的忧伤都是狗屁。",
author: "网友",
categories: ["格局"]
},
{
text: "失败并不可怕,可怕的是你还相信这句话。",
author: "网友",
categories: ["毒鸡汤"]
},
{
text: "命,是弱者的借口;运,是强者的谦卑。",
author: "网络",
categories: ["励志"]
},
{
text: "锦上添花永远比不上雪中送炭。",
author: "沙雕视频-云深不知处,然有六出焉",
categories: ["格局"]
},
{
text: "还万一成功,那九千九百九十九的失败概率你是提都不提。",
author: "沙雕视频-云深不知处,然有六出焉",
categories: ["毒鸡汤"]
},
{
text: "你以为有钱人很快乐吗?他们的快乐你根本想象不到。",
author: "网友",
categories: ["毒鸡汤"]
},
{
text: "没有必要的东西就敷衍而过,必要的东西就尽力而做!",
author: "番剧-冰菓",
categories: ["学习方法"]
},
{
text: "世界上的事情,最忌讳的就是个十全十美,你看那天上的月亮,一旦圆满了,马上就要亏厌;树上的果子,一旦熟透了,马上就要坠落。凡事总要稍留欠缺,才能持恒。",
author: "莫言《晚熟的人》",
categories: ["格局"]
},
{
text: "我们花了两年学会说话,却要花上六十年来学会闭嘴。大多数时候,我们说得越多,彼此的距离却越远,矛盾也越多。在沟通中,大多数人总是急于表达自己,一吐为快,却一点也不懂对方。两年学说话,一生学闭嘴。懂与不懂,不多说。心乱心静,慢慢说。若真没话,就别说。",
author: "莫言《晚熟的人》",
categories: ["格局"]
},
{
text: "除了生死,都是擦伤!",
author: "孙伟",
categories: ["格局"]
},
];
// 获取元素
const quoteText = getElement('quote-text');
const quoteAuthor = getElement('quote-author');
const refreshBtn = getElement('refresh-btn');
const likeBtn = getElement('like-btn');
const categoryContainer = getElement('category-container');
const quotesList = getElement('quotes-list');
const pagination = getElement('pagination');
// 状态
let currentQuoteIndex = 0;
let isLiked = false;
let currentCategory = '全部';
let currentPage = 1;
const itemsPerPage = 6;
// 所有可用标签
const allCategories = Array.from(new Set(quotes.flatMap(quote => quote.categories)));
// 初始化分类按钮
function initCategoryButtons() {
// 清空现有按钮(保留"全部"按钮)
categoryContainer.innerHTML = '';
// 添加"全部"按钮
const allButton = document.createElement('button');
allButton.className = 'category-btn';
allButton.textContent = '全部';
allButton.addEventListener('click', () => {
currentPage = 1;
setActiveCategory('全部');
renderQuotesList(quotes);
renderPagination(quotes);
});
categoryContainer.appendChild(allButton);
// 添加其他分类按钮
allCategories.forEach(category => {
const button = document.createElement('button');
button.className = 'category-btn';
button.textContent = category;
button.addEventListener('click', () => {
currentPage = 1;
setActiveCategory(category);
const filteredQuotes = filterQuotesByCategory(category);
renderQuotesList(filteredQuotes);
renderPagination(filteredQuotes);
});
categoryContainer.appendChild(button);
});
// 默认激活"全部"按钮
setActiveCategory('全部');
}
function setActiveCategory(category) {
currentCategory = category;
const buttons = categoryContainer.querySelectorAll('.category-btn');
buttons.forEach(btn => {
if (btn.textContent === category) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
}
function filterQuotesByCategory(category) {
if (category === '全部') {
return quotes;
} else {
return quotes.filter(quote => quote.categories.includes(category));
}
}
function setRandomQuote() {
// 生成随机索引
let randomIndex;
do {
randomIndex = Math.floor(Math.random() * quotes.length);
} while (randomIndex === currentQuoteIndex);
currentQuoteIndex = randomIndex;
const quote = quotes[randomIndex];
// 添加淡入淡出效果
quoteText.style.opacity = '0';
quoteAuthor.style.opacity = '0';
setTimeout(() => {
// 更新名言内容
quoteText.textContent = quote.text;
quoteAuthor.textContent = `—— ${quote.author}`;
// 淡入效果
quoteText.style.opacity = '1';
quoteAuthor.style.opacity = '1';
}, 300);
}
function toggleLike() {
isLiked = !isLiked;
if (isLiked) {
likeBtn.innerHTML = '<i class="fa fa-heart" style="color: var(--red-500);"></i>';
// 添加心跳动画
likeBtn.querySelector('i').classList.add('animate-pulse');
setTimeout(() => {
likeBtn.querySelector('i').classList.remove('animate-pulse');
}, 1000);
} else {
likeBtn.innerHTML = '<i class="fa fa-heart-o"></i>';
}
}
function renderQuotesList(quotesToRender) {
quotesList.innerHTML = '';
// 计算当前页显示的名言范围
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(startIndex + itemsPerPage, quotesToRender.length);
const currentQuotes = quotesToRender.slice(startIndex, endIndex);
if (currentQuotes.length === 0) {
const emptyMessage = document.createElement('div');
emptyMessage.className = 'quote-item';
emptyMessage.textContent = '没有找到相关名言';
quotesList.appendChild(emptyMessage);
return;
}
currentQuotes.forEach(quote => {
const quoteItem = document.createElement('div');
quoteItem.className = 'quote-item';
// 创建标签元素
const tagsHtml = quote.categories.map(category =>
`<span class="quote-tag">${category}</span>`
).join('');
quoteItem.innerHTML = `
<p class="text-neutral-800 mb-2">${quote.text}</p>
<div class="flex justify-between items-center">
<p class="text-neutral-600 text-sm italic">—— ${quote.author}</p>
<div class="flex">
${tagsHtml}
</div>
</div>
`;
quotesList.appendChild(quoteItem);
});
}
function renderPagination(quotesToRender) {
pagination.innerHTML = '';
const totalPages = Math.ceil(quotesToRender.length / itemsPerPage);
if (totalPages <= 1) {
return;
}
// 上一页按钮
const prevButton = document.createElement('button');
prevButton.className = `page-btn ${currentPage === 1 ? 'disabled' : ''}`;
prevButton.innerHTML = '<i class="fa fa-chevron-left"></i>';
prevButton.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderQuotesList(quotesToRender);
renderPagination(quotesToRender);
}
});
pagination.appendChild(prevButton);
// 页码按钮
for (let i = 1; i <= totalPages; i++) {
const pageButton = document.createElement('button');
pageButton.className = `page-btn ${currentPage === i ? 'active' : ''}`;
pageButton.textContent = i;
pageButton.addEventListener('click', () => {
currentPage = i;
renderQuotesList(quotesToRender);
renderPagination(quotesToRender);
});
pagination.appendChild(pageButton);
}
// 下一页按钮
const nextButton = document.createElement('button');
nextButton.className = `page-btn ${currentPage === totalPages ? 'disabled' : ''}`;
nextButton.innerHTML = '<i class="fa fa-chevron-right"></i>';
nextButton.addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
renderQuotesList(quotesToRender);
renderPagination(quotesToRender);
}
});
pagination.appendChild(nextButton);
}
// 初始化应用
function init() {
// 添加Font Awesome
const faLink = document.createElement('link');
faLink.rel = 'stylesheet';
faLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css';
document.head.appendChild(faLink);
// 设置随机名言
setRandomQuote();
// 绑定事件
refreshBtn.addEventListener('click', setRandomQuote);
likeBtn.addEventListener('click', toggleLike);
// 初始化分类按钮
initCategoryButtons();
// 初始渲染名言列表和分页
renderQuotesList(quotes);
renderPagination(quotes);
}
// 启动应用
init();
})();
</script>
{% endraw %}

3.3.6 关于我页面

效果见本博客关于我页面,代码如下所示:

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
{% raw %}
<!-- 独立个人介绍div - 使用Shadow DOM实现完全隔离 -->
<div id="personal-profile-container"></div>
<script>
// 使用IIFE封装所有代码,避免污染全局作用域
(function() {
// 创建Shadow DOM容器
const container = document.getElementById('personal-profile-container');
const shadowRoot = container.attachShadow({ mode: 'open' });

// 添加样式和内容到Shadow DOM
shadowRoot.innerHTML = `
<style>
/* 导入字体图标 - 只在Shadow DOM内生效 */
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css');

/* 个人介绍组件的样式 - 只作用于Shadow DOM内部 */
:host {
--primary-color: #4a6bdf;
--secondary-color: #3a56c0;
--text-color: #333;
--light-bg: #f9f9f9;
--border-color: #e1e4e8;
--icon-bg: #f0f4ff;

display: block;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: white;
border-radius: 12px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
overflow: hidden;
margin: 20px 0;
padding: 25px;
width: 1000px;
max-width: 100%;
box-sizing: border-box;
}

.profile-header {
display: flex;
flex-wrap: wrap;
gap: 30px;
margin-bottom: 25px;
}

.avatar-container {
width: 200px;
flex-shrink: 0;
}

.avatar {
width: 200px;
height: 270px;
border-radius: 10px;
object-fit: cover;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border: 3px solid white;
}

.avatar:hover {
transform: scale(1.03);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.info-container {
flex: 1;
min-width: 300px;
}

h2 {
color: var(--primary-color);
margin-top: 0;
margin-bottom: 15px;
font-size: 28px;
}

.bio {
color: #555;
line-height: 1.6;
margin-bottom: 20px;
}

.basic-info {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 15px;
margin-bottom: 15px;
}

.info-item {
display: flex;
align-items: center;
font-size: 15px;
}

.info-item i {
display: inline-flex;
align-items: center;
justify-content: center;
margin-right: 12px;
color: white;
background-color: var(--primary-color);
width: 32px;
height: 32px;
border-radius: 50%;
text-align: center;
font-size: 16px;
transition: all 0.2s ease;
}

.info-item:hover i {
background-color: var(--secondary-color);
transform: scale(1.1);
}

.section-title {
color: var(--primary-color);
border-bottom: 2px solid var(--border-color);
padding-bottom: 8px;
margin: 25px 0 18px 0;
font-size: 20px;
display: flex;
align-items: center;
}

.section-title i {
margin-right: 10px;
font-size: 22px;
}

.skills {
display: flex;
flex-wrap: wrap;
gap: 10px;
}

.skill-tag {
background-color: var(--light-bg);
padding: 8px 15px;
border-radius: 20px;
font-size: 14px;
transition: all 0.2s ease;
border: 1px solid var(--border-color);
cursor: pointer;
text-decoration: none;
color: inherit;
display: inline-block;
}

.skill-tag:hover {
background-color: var(--primary-color);
color: white;
transform: translateY(-3px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-color: var(--primary-color);
}

.links {
display: flex;
flex-wrap: wrap;
gap: 12px;
}

.links a {
display: inline-flex;
align-items: center;
color: var(--primary-color);
text-decoration: none;
padding: 10px 15px;
border-radius: 8px;
transition: all 0.2s ease;
background-color: var(--icon-bg);
border: 1px solid var(--border-color);
}

.links a:hover {
background-color: var(--primary-color);
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.links a i {
margin-right: 8px;
font-size: 18px;
}

.achievements {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 15px;
margin-top: 15px;
}

.achievement-item {
background-color: var(--light-bg);
padding: 15px;
border-radius: 8px;
border-left: 4px solid var(--primary-color);
transition: all 0.2s ease;
}

.achievement-item:hover {
transform: translateY(-3px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.achievement-title {
font-weight: bold;
margin-bottom: 5px;
color: var(--primary-color);
}

.achievement-date {
font-size: 13px;
color: #666;
margin-bottom: 8px;
}

.achievement-desc {
font-size: 14px;
line-height: 1.5;
color: #555;
}

@media (max-width: 850px) {
:host {
width: 95%;
padding: 20px;
}

.avatar {
width: 150px;
height: 150px;
}

.avatar-container {
width: 150px;
}

.basic-info {
grid-template-columns: 1fr;
}

.achievements {
grid-template-columns: 1fr;
}
}
</style>

<div id="personal-profile">
<!-- 内容将由JavaScript动态生成 -->
</div>
`;

// 获取Shadow DOM内的元素
const profileContainer = shadowRoot.getElementById('personal-profile');

// 个人资料数据
const profileData = {
name: '孙伟',
birth: '2003-02-20',
qq: '1810915429',
wechat: 'wxid_y3xw0pdsosod22',
email: '1810915429@qq.com',
phone: '19195499101',
skills: [
{ name: 'Ps', url: 'https://blog.sunwei.online/tags/PS/' },
{ name: 'Butterfly', url: 'https://blog.sunwei.online/tags/Butterfly/' },
{ name: 'Markdown', url: 'https://blog.sunwei.online/tags/Markdown/' }
],
bio: '一名普普通通的本科研究生,热爱编程,立志成为一名优秀の程序员。',
achievements: [
{
title: "校级奖学金",
date: "2021年-2025年",
description: "于大学期间获得“三等奖学金”2份,“二等奖学金”1份。"
},
{
title: "全国大学生数学建模竞赛",
date: "2023年9月",
description: "在23年的全国大学生数学建模竞赛中,为解决a题:“定日镜场的优化设计”,作为编程手,获得“国一”。"
},
{
title: "软考中级",
date: "2024年6月",
description: "于软考中级中获得“-软件设计师”证书。"
},
{
title: "英语四级",
date: "2022年12月",
description: "获得全国大学生英语四级证书。"
}
]
};

// 生成HTML内容
profileContainer.innerHTML = `
<div class="profile-header">
<div class="avatar-container">
<img src="https://pic1.imgdb.cn/item/6856a67258cb8da5c860a617.jpg"
alt="头像" class="avatar">
</div>
<div class="info-container">
<h2>${profileData.name}</h2>
<p class="bio">${profileData.bio}</p>

<div class="basic-info">
<div class="info-item">
<i class="fas fa-phone-alt"></i>
<span>${profileData.phone}</span>
</div>
<div class="info-item">
<i class="fas fa-envelope"></i>
<span>${profileData.email}</span>
</div>
<div class="info-item">
<i class="fab fa-qq"></i>
<span>${profileData.qq}</span>
</div>
<div class="info-item">
<i class="fab fa-weixin"></i>
<span>${profileData.wechat}</span>
</div>
<div class="info-item">
<i class="fas fa-birthday-cake"></i>
<span>${profileData.birth}</span>
</div>
<div class="info-item">
<i class="fas fa-map-marker-alt"></i>
<span>中国 · 宜春</span>
</div>
</div>
</div>
</div>

<h3 class="section-title"><i class="fas fa-link"></i>我的网站</h3>
<div class="links">
<a href="https://www.sunwei.online/" target="_blank">
<i class="fas fa-globe"></i>主页
</a>
<a href="https://blog.sunwei.online/" target="_blank">
<i class="fas fa-globe"></i>博客
</a>
<a href="https://status.sunwei.online/" target="_blank">
<i class="fas fa-globe"></i>状态
</a>
<a href="https://qexo.sunwei.online/" target="_blank">
<i class="fas fa-globe"></i>后台
</a>
</div>

<h3 class="section-title"><i class="fas fa-code"></i>我的技能</h3>
<div class="skills">
${profileData.skills.map(skill => `
<a href="${skill.url}" target="_blank" class="skill-tag">${skill.name}</a>
`).join('')}
</div>

<h3 class="section-title"><i class="fas fa-trophy"></i>我的成就</h3>
<div class="achievements">
${profileData.achievements.map(achievement => `
<div class="achievement-item">
<div class="achievement-title">${achievement.title}</div>
<div class="achievement-date">${achievement.date}</div>
<div class="achievement-desc">${achievement.description}</div>
</div>
`).join('')}
</div>
`;

// 添加交互效果 - 只在Shadow DOM内生效
const avatar = profileContainer.querySelector('.avatar');
avatar.addEventListener('click', function() {
this.style.transform = 'scale(0.95)';
setTimeout(() => {
this.style.transform = 'scale(1)';
}, 200);
});

// 为链接添加点击动画
const links = profileContainer.querySelectorAll('.links a');
links.forEach(link => {
link.addEventListener('click', function(e) {
this.style.transform = 'scale(0.98)';
setTimeout(() => {
this.style.transform = '';
}, 200);
});
});

// 为技能标签添加点击效果
const skillTags = profileContainer.querySelectorAll('.skill-tag');
skillTags.forEach(tag => {
tag.addEventListener('click', function() {
this.style.transform = 'scale(0.95)';
setTimeout(() => {
this.style.transform = '';
}, 200);
});
});

// 为成就项添加点击效果
const achievementItems = profileContainer.querySelectorAll('.achievement-item');
achievementItems.forEach(item => {
item.addEventListener('click', function() {
this.style.transform = 'scale(0.98)';
setTimeout(() => {
this.style.transform = '';
}, 200);
});
});
})();
</script>
{% endraw %}

3.3.7 小说收藏页面

效果见本博客阅读分类中收藏的文章,代码如下所示:

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
{% raw %}
<div id="short-story-container">
<script>
(function () {
const container = document.getElementById('short-story-container');
const shadowRoot = container.attachShadow({ mode: 'open' });
// 样式调整:魔法书风格
const style = document.createElement('style');
style.textContent = `
:host {
display: block;
font-family: 'Times New Roman', Georgia, serif;
max-width: 900px;
margin: 20px auto;
padding: 0;
position: relative;
background: #f5e7c1 url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23f5e7c1"/><path d="M0,50 Q25,40 50,50 T100,50" stroke="%23e8d9b5" fill="none" stroke-width="1"/></svg>');
border: 15px solid transparent;
border-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="94" height="94" x="3" y="3" fill="none" stroke="%23b38e6d" stroke-width="6" rx="5" ry="5"/><rect width="88" height="88" x="6" y="6" fill="none" stroke="%23d4b78f" stroke-width="4" rx="3" ry="3"/></svg>') 20;
box-shadow: 0 0 25px rgba(0,0,0,0.3),
inset 0 0 50px rgba(179, 142, 109, 0.5),
0 0 10px 5px rgba(179, 142, 109, 0.3);
/* 移除rotateX变换,保持宽度一致 */
}
/* 魔法书装饰元素 */
:host::before {
content: "";
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
width: 60%;
height: 15px;
background: #b38e6d;
border-radius: 0 0 10px 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
}
:host::after {
content: "";
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 60%;
height: 15px;
background: #b38e6d;
border-radius: 10px 10px 0 0;
box-shadow: 0 -2px 5px rgba(0,0,0,0.3);
}
/* 标题 + 作者 容器 */
.title-wrap {
border-bottom: 2px solid #b38e6d;
padding: 15px 30px 10px;
margin: 0;
background: linear-gradient(to right, transparent, rgba(179, 142, 109, 0.2), transparent);
position: relative;
}
.title-wrap::before,
.title-wrap::after {
content: "✧";
position: absolute;
top: 50%;
transform: translateY(-50%);
color: #b38e6d;
font-size: 24px;
}
.title-wrap::before {
left: 5px;
}
.title-wrap::after {
right: 5px;
}
.story-title {
text-align: center;
color: #5a3921;
font-size: 32px;
margin: 0 0 5px;
font-weight: bold;
text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
letter-spacing: 1px;
font-family: 'SimSun', '宋体', serif;
}
.author {
text-align: center;
font-style: italic;
color: #7f6b5a;
margin: 0;
font-size: 18px;
letter-spacing: 1px;
}
/* 正文容器 */
.story-content {
line-height: 1.8;
color: #4a3a2a;
text-indent: 2em;
background: rgba(245, 231, 193, 0.7);
padding: 25px 40px;
margin: 0;
border-left: 1px solid rgba(179, 142, 109, 0.5);
border-right: 1px solid rgba(179, 142, 109, 0.5);
border-bottom: 1px solid rgba(179, 142, 109, 0.5);
position: relative;
}
.story-content::before {
content: "";
position: absolute;
top: 0;
left: 20px;
right: 20px;
height: 1px;
background: linear-gradient(to right, transparent, #b38e6d, transparent);
}
.story-content p {
margin-bottom: 1em;
font-size: 18px;
}
/* 读后感部分 */
.reflection {
background: rgba(232, 220, 200, 0.7);
padding: 25px 40px;
border-left: 4px solid #b38e6d;
margin: 0;
position: relative;
border-bottom: 1px solid rgba(179, 142, 109, 0.5);
}
.reflection::before {
content: "";
position: absolute;
top: 0;
left: 20px;
right: 20px;
height: 1px;
background: linear-gradient(to right, transparent, #b38e6d, transparent);
}
.reflection-title {
color: #5a3921;
margin-top: 0;
font-family: 'SimSun', '宋体', serif;
text-align: left;
font-size: 24px;
border-bottom: 1px dashed #b38e6d;
padding-bottom: 10px;
}
/* 交互效果 */
.story-title:hover {
color: #8b4513;
cursor: pointer;
text-shadow: 1px 1px 3px rgba(139, 69, 19, 0.3);
}
/* 修改后的魔法书翻页效果 - 只旋转Y轴 */
@keyframes pageTurn {
0% { transform: rotateY(0deg); }
50% { transform: rotateY(10deg); }
100% { transform: rotateY(0deg); }
}
:host:hover {
animation: pageTurn 2s ease-in-out;
}
`;
shadowRoot.appendChild(style);
// HTML 结构
const content = document.createElement('div');
content.innerHTML = `
<div class="title-wrap">
<p class="story-title">努力,终会与成功相遇</p>
<p class="author">作者:余兢兢</p>
</div>
<div class="story-content">
<p>今天的成功是因为昨天的积累,明天的成功则依赖于今天的努力,只要不轻言放弃,坚持如初,追梦到底,成功终会与我们相遇。</p>
<p>三年前,我还是一名刚入学的高中生,天真幼稚,不谙世事,每天除了追剧看小说,就是睡觉打游戏。那时年少,对梦想并没有什么清晰的概念,只知道一味地玩耍疯闹。即使每天听着高三党们书声琅琅,看着他们快步如飞,争分夺秒温书做题,也并没有太多感触,只是天真地以为高考离我还远,考大学也没有那么难。</p>
</div>
<div class="reflection">
<h3 class="reflection-title">我的读后感</h3>
<p>还没看!</p>
<p>还没看!</p>
<p>还没看!</p>
<p>还没看!</p>
</div>
`;
shadowRoot.appendChild(content);
// 交互逻辑
const title = shadowRoot.querySelector('.story-title');
title.addEventListener('click', function() {
this.style.color = this.style.color === 'rgb(139, 69, 19)' ? '#5a3921' : '#8b4513';
});
})();
</script>
</div>
{% endraw %}

4. 列表/表格

4.1 无序列表⭐

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note default no-icon %}
* Java
* Python
* ...

+ Java
+ Python
+ ...

- Java
- Python
- ...
{% endnote %}

• 注意内容前有1空格
• 真实情况下,直接*就是,但那点是中间透明的,影响观看,所以还是加个框吧!
• 其实可以直接用onenote中复制粘贴的那个”• “,是切切实实的实心黑点,我也经常用!

  • Java
  • Python
  • Java
  • Python
  • Java
  • Python

4.2 有序列表⭐

1
2
3
4
1. 内容1
2. 内容2
3.
4.

• 注意内容前有1空格

  1. 内容1
  2. 内容2

4.3 单选列表

1
2
{% radio green checked, 支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %}
{% radio red, 红色 %}

• 分别代表“颜色、是否选择、内容”!
• 颜色: red,yellow,green,cyan,blue,gray
• 选中状态: checked,填入这个后会默认选择此列表!

支持简单的 markdown 语法

红色

4.4 复选列表

1
2
3
4
5
6
7
{% checkbox 纯文本测试 %}
{% checkbox checked, 支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %}
{% checkbox red, 支持自定义颜色 %}
{% checkbox blue checked, 蓝色 + 默认选中 %}
{% checkbox plus green checked, 增加 %}
{% checkbox minus yellow checked, 减少 %}
{% checkbox times red checked, 叉 %}

• 分别为“样式、颜色、是否默认选择、内容”
• 样式: plus, minus, times
• 颜色: red,yellow,green,cyan,blue,gray
• 选中状态: checked

纯文本测试

支持简单的 markdown 语法

支持自定义颜色

蓝色 + 默认选中

增加

减少

4.5 表格⭐

1
2
3
4
5
| 项目标号 | 资金     | 备注 |
| -------- | -------- | ---- |
| 1 | 100,000 | 无 |
| 2 | 200,000 | 无 |
| 3 | 300,600 | 重要 |
项目标号 资金 备注
1 100,000
2 200,000
3 300,600 重要

5. 字体样式

5.1 多级标题⭐

1
2
3
4
5
6
# H1
## H2
### H3
#### H4
##### H5
###### H6

• 尽量按规则来,先一级,再二级……!

见文章标题……

5.2 Markdown文字样式⭐

1
2
3
4
5
6
7
8
9
<u>下划线</u>
**加粗**
*斜体*
`高亮`
~~删除线~~
<font size = 5>5号字</font>
<font face="黑体">黑体</font>
<font color=blue>蓝色</font>
<table><tr><td bgcolor=MistyRose>表格背景色是:MistyRo

下划线
加粗
斜体
高亮
删除线
5号字
黑体
蓝色

表格背景色是:MistyRosen,内容略

5.3 Butterfly文字样式

1
2
3
4
5
6
{% u 下划线 %} 
{% emp 着重号 %}
{% wavy 波浪线 %}
{% del 删除线 %}
{% kbd 键盘样式 %}
{% psw 密码样式 %}

下划线
着重号
波浪线
删除线
键盘样式
密码样式

5.4 文字底纹⭐

1
我是{% bubble,"内容","#868fd7" %}我是

• 分别对应“加底纹内容、底纹颜色”
• 颜色:绿(#1db675)……

我是内容我是

5.5 行内文本 span

1
2
{% span red, 红色字 %}
{% span center logo large, Volantis %}

• 第1行代码,如果想换字体颜色直接将red换成相应英文,如:“yellow、green、cyan、blue、gray……”就行!
• 第2行代码,参数分别为:“对齐方式、字体、大小、内容”,他们对应的值可以为
  对齐方式:left, center, right
  字体:logo, code
  大小:small, h4, h3, h2, h1, large, huge, ultra

红色字

5.6 段落文本 p

1
2
{% p red, 红色 %}
{% p center logo large, Volantis %}

• 跟上面那个span标签基本类似,就不详细讲了,只是一个为行内的,一个为段落的(p标签用一个就会换下行,而span标签则不会)

红色

5.7 诗词标签 poem

1
2
3
4
5
6
7
8
9
10
11
12
{% poem 水调歌头,苏轼 %}
丙辰中秋,欢饮达旦,大醉,作此篇,兼怀子由。
明月几时有?把酒问青天。
不知天上宫阙,今夕是何年?
我欲乘风归去,又恐琼楼玉宇,高处不胜寒。
起舞弄清影,何似在人间?

转朱阁,低绮户,照无眠。
不应有恨,何事长向别时圆?
人有悲欢离合,月有阴晴圆缺,此事古难全。
但愿人长久,千里共婵娟。
{% endpoem %}

• 只要修改一下代码第1行的诗词名&&作者,然后把诗歌内容放标签中间就行!

水调歌头
苏轼

丙辰中秋,欢饮达旦,大醉,作此篇,兼怀子由。
明月几时有?把酒问青天。
不知天上宫阙,今夕是何年?
我欲乘风归去,又恐琼楼玉宇,高处不胜寒。
起舞弄清影,何似在人间?

转朱阁,低绮户,照无眠。
不应有恨,何事长向别时圆?
人有悲欢离合,月有阴晴圆缺,此事古难全。
但愿人长久,千里共婵娟。

5.8 引用文献 reference

1
2
Akilarの糖果屋{% referto '[1]','Akilarの糖果屋群聊简介' %}
{% referfrom '[1]','Akilarの糖果屋','Akilarの糖果屋 - Akilar.top' %}

Akilarの糖果屋[1]Akilarの糖果屋群聊简介参考资料

5.9 链接字⭐

1
[github网站](https://guides.github.com/features/mastering-markdown/)

6. 标签框子

6.1 进度条 progress⭐

1
{% progress 10 red 进度条样式预览 %}

• 分别控制进度条”进度、颜色、条中内容”!

进度条样式预览

6.2 note标签(引用)

类型一:Butterfly主题自带的样式!

1.simple样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note simple %}默认 提示块标签{% endnote %}

{% note default simple %}default 提示块标签{% endnote %}

{% note primary simple %}primary 提示块标签{% endnote %}

{% note success simple %}success 提示块标签{% endnote %}

{% note info simple %}info 提示块标签{% endnote %}

{% note warning simple %}warning 提示块标签{% endnote %}

{% note danger simple %}danger 提示块标签{% endnote %}

2.modern样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note modern %}默认 提示块标签{% endnote %}

{% note default modern %}default 提示块标签{% endnote %}

{% note primary modern %}primary 提示块标签{% endnote %}

{% note success modern %}success 提示块标签{% endnote %}

{% note info modern %}info 提示块标签{% endnote %}

{% note warning modern %}warning 提示块标签{% endnote %}

{% note danger modern %}danger 提示块标签{% endnote %}

3.flat样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note flat %}默认 提示块标签{% endnote %}

{% note default flat %}default 提示块标签{% endnote %}

{% note primary flat %}primary 提示块标签{% endnote %}

{% note success flat %}success 提示块标签{% endnote %}

{% note info flat %}info 提示块标签{% endnote %}

{% note warning flat %}warning 提示块标签{% endnote %}

{% note danger flat %}danger 提示块标签{% endnote %}

4.disabled样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note disabled %}默认 提示块标签{% endnote %}

{% note default disabled %}default 提示块标签{% endnote %}

{% note primary disabled %}primary 提示块标签{% endnote %}

{% note success disabled %}success 提示块标签{% endnote %}

{% note info disabled %}info 提示块标签{% endnote %}

{% note warning disabled %}warning 提示块标签{% endnote %}

{% note danger disabled %}danger 提示块标签{% endnote %}

5.no-icon样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note no-icon %}默认 提示块标签{% endnote %}

{% note default no-icon %}default 提示块标签{% endnote %}

{% note primary no-icon %}primary 提示块标签{% endnote %}

{% note success no-icon %}success 提示块标签{% endnote %}

{% note info no-icon %}info 提示块标签{% endnote %}

{% note warning no-icon %}warning 提示块标签{% endnote %}

{% note danger no-icon %}danger 提示块标签{% endnote %}

• 依次为:图标+样式!
常见5种样式:“style、simple、modern、flat、disabled”!
常见6种图标:“default、primary、success、info、warning、danger(没有就默认无图标)”!

1.simple样式

默认 提示块标签

default 提示块标签

primary 提示块标签

success 提示块标签

info 提示块标签

warning 提示块标签

danger 提示块标签

2.`modern`样式

默认 提示块标签

default 提示块标签

primary 提示块标签

success 提示块标签

info 提示块标签

warning 提示块标签

danger 提示块标签

3.flat样式

默认 提示块标签

default 提示块标签

primary 提示块标签

success 提示块标签

info 提示块标签

warning 提示块标签

danger 提示块标签

4.disabled样式

默认 提示块标签

default 提示块标签

primary 提示块标签

success 提示块标签

info 提示块标签

warning 提示块标签

danger 提示块标签

5.no-icon样式

默认 提示块标签

default 提示块标签

primary 提示块标签

success 提示块标签

info 提示块标签

warning 提示块标签

danger 提示块标签

类型二:处来引入的图标样式

1.simple样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note 'fab fa-cc-visa' simple %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note blue 'fas fa-bullhorn' simple %}2021年快到了....{% endnote %}

{% note pink 'fas fa-car-crash' simple %}小心开车 安全至上{% endnote %}

{% note red 'fas fa-fan' simple%}这是三片呢?还是四片?{% endnote %}

{% note orange 'fas fa-battery-half' simple %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note purple 'far fa-hand-scissors' simple %}剪刀石头布{% endnote %}

{% note green 'fab fa-internet-explorer' simple %}前端最讨厌的浏览器{% endnote %}

2.modern样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note 'fab fa-cc-visa' modern %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note blue 'fas fa-bullhorn' modern %}2021年快到了....{% endnote %}

{% note pink 'fas fa-car-crash' modern %}小心开车 安全至上{% endnote %}

{% note red 'fas fa-fan' modern%}这是三片呢?还是四片?{% endnote %}

{% note orange 'fas fa-battery-half' modern %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note purple 'far fa-hand-scissors' modern %}剪刀石头布{% endnote %}

{% note green 'fab fa-internet-explorer' modern %}前端最讨厌的浏览器{% endnote %}

3.flat样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note 'fab fa-cc-visa' flat %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note blue 'fas fa-bullhorn' flat %}2021年快到了....{% endnote %}

{% note pink 'fas fa-car-crash' flat %}小心开车 安全至上{% endnote %}

{% note red 'fas fa-fan' flat%}这是三片呢?还是四片?{% endnote %}

{% note orange 'fas fa-battery-half' flat %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note purple 'far fa-hand-scissors' flat %}剪刀石头布{% endnote %}

{% note green 'fab fa-internet-explorer' flat %}前端最讨厌的浏览器{% endnote %}

4.disabled样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note 'fab fa-cc-visa' disabled %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note blue 'fas fa-bullhorn' disabled %}2021年快到了....{% endnote %}

{% note pink 'fas fa-car-crash' disabled %}小心开车 安全至上{% endnote %}

{% note red 'fas fa-fan' disabled %}这是三片呢?还是四片?{% endnote %}

{% note orange 'fas fa-battery-half' disabled %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note purple 'far fa-hand-scissors' disabled %}剪刀石头布{% endnote %}

{% note green 'fab fa-internet-explorer' disabled %}前端最讨厌的浏览器{% endnote %}

5.no-icon样式

1
2
3
4
5
6
7
8
9
10
11
12
13
{% note no-icon %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note blue no-icon %}2021年快到了....{% endnote %}

{% note pink no-icon %}小心开车 安全至上{% endnote %}

{% note red no-icon %}这是三片呢?还是四片?{% endnote %}

{% note orange no-icon %}你是刷 Visa 还是 UnionPay{% endnote %}

{% note purple no-icon %}剪刀石头布{% endnote %}

{% note green no-icon %}前端最讨厌的浏览器{% endnote %}

• 参数分别对应:颜色+图标+样式!
颜色:default、blue、pink、red、purple、orange、green
图标:可配置自定义 icon (只支持 fontawesome 图标)
样式:style、simple、modern、flat、disabled

1.simple样式

你是刷 Visa 还是 UnionPay

2021年快到了….

小心开车 安全至上

这是三片呢?还是四片?

你是刷 Visa 还是 UnionPay

剪刀石头布

前端最讨厌的浏览器

2.modern样式

你是刷 Visa 还是 UnionPay

2021年快到了….

小心开车 安全至上

这是三片呢?还是四片?

你是刷 Visa 还是 UnionPay

剪刀石头布

前端最讨厌的浏览器

3.flat样式

你是刷 Visa 还是 UnionPay

2021年快到了….

小心开车 安全至上

这是三片呢?还是四片?

你是刷 Visa 还是 UnionPay

剪刀石头布

前端最讨厌的浏览器

4.disabled样式

你是刷 Visa 还是 UnionPay

2021年快到了….

小心开车 安全至上

这是三片呢?还是四片?

你是刷 Visa 还是 UnionPay

剪刀石头布

前端最讨厌的浏览器

5.no-icon样式

你是刷 Visa 还是 UnionPay

2021年快到了….

小心开车 安全至上

这是三片呢?还是四片?

你是刷 Visa 还是 UnionPay

剪刀石头布

前端最讨厌的浏览器

6.3 tip标签(上标)

1
2
3
4
5
6
7
8
9
10
11
{% tip info %}info{% endtip %}
{% tip success %}success{% endtip %}
{% tip error %}error{% endtip %}
{% tip warning %}warning{% endtip %}
{% tip bolt %}bolt{% endtip %}
{% tip ban %}ban{% endtip %}
{% tip home %}home{% endtip %}
{% tip sync %}sync{% endtip %}
{% tip cogs %}cogs{% endtip %}
{% tip key %}key{% endtip %}
{% tip bell %}bell{% endtip %}

• 就只有一个参数“样式”,可以为:info,success,error,warning,bolt,ban,home,sync,cogs,key,bell

info

success

error

warning

bolt

ban

home

sync

cogs

key

bell

6.4 anima标签(动态)

1.On DOM load(当页面加载时显示动画)

1
2
{% tip warning faa-horizontal animated %}warning{% endtip %}
{% tip ban faa-flash animated %}ban{% endtip %}

2.调整动画速度

1
2
{% tip warning faa-horizontal animated faa-fast %}warning{% endtip %}
{% tip ban faa-flash animated faa-slow %}ban{% endtip %}

3.On hover(当鼠标悬停时显示动画)

1
2
{% tip warning faa-horizontal animated-hover %}warning{% endtip %}
{% tip ban faa-flash animated-hover %}ban{% endtip %}

4.On parent hover(当鼠标悬停在父级元素时显示动画)

1
2
{% tip warning faa-parent animated-hover %}<p class="faa-horizontal">warning</p>{% endtip %}
{% tip ban faa-parent animated-hover %}<p class="faa-flash">ban</p>{% endtip %}

1.On DOM load(当页面加载时显示动画)

warning

ban

2.调整动画速度

warning

ban

3.On hover(当鼠标悬停时显示动画)

warning

ban

4.On parent hover(当鼠标悬停在父级元素时显示动画)

warning

ban

6.5 wow标签(特效)

1.flip动画效果。

1
2
3
4
5
{% wow animate__zoomIn,5s,5s,100,10 %}
{% note blue 'fas fa-bullhorn' modern%}
`zoomIn`动画效果,持续`5s`,延时`5s`,离底部`100`距离时启动,重复`10`次
{% endnote %}
{% endwow %}

2.zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10次

1
2
3
4
5
{% wow animate__zoomIn,5s,5s,100,10 %}
{% note blue 'fas fa-bullhorn' modern%}
`zoomIn`动画效果,持续`5s`,延时`5s`,离底部`100`距离时启动,重复`10`次
{% endnote %}
{% endwow %}

3.slideInRight动画效果,持续5s,延时5s

1
2
3
4
5
{% wow animate__slideInRight,5s,5s %}
{% note orange 'fas fa-car' modern%}
`slideInRight`动画效果,持续`5s`,延时`5s`。
{% endnote %}
{% endwow %}

4.heartBeat动画效果,延时5s,重复10次。此处注意不用的参数位置要留空,用逗号间隔。

1
2
3
4
5
{% wow animate__heartBeat,,5s,,10 %}
{% note red 'fas fa-battery-half' modern%}
`heartBeat`动画效果,延时`5s`,重复`10`次。
{% endnote %}
{% endwow %}
  1. animate: 动画样式,效果详见animate.css参考文档
  2. duration: 选填项,动画持续时间,单位可以是ms也可以是s。例如3s700ms
  3. delay: 选填项,动画开始的延迟时间,单位可以是ms也可以是s。例如3s700ms
  4. offset: 选填项,开始动画的距离(相对浏览器底部)
  5. iteration: 选填项,动画重复的次数

1.flip动画效果。

zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10

2.zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10次

zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10

3.slideInRight动画效果,持续5s,延时5s

slideInRight动画效果,持续5s,延时5s

4.heartBeat动画效果,延时5s,重复10次。此处注意不用的参数位置要留空,用逗号间隔。

heartBeat动画效果,延时5s,重复10次。

7. 网站链接卡片

1
{% link 糖果屋教程贴, https://akilar.top/posts/615e2dec/, https://cdn.cbd.int/akilar-candyassets@1.0.36/image/siteicon/favicon.ico %}

• 参数依次为:连接名 + 链接地址 + 头像。

7.2 按钮链接 btns

  1. 样式一
1
2
3
{% btns circle grid5 %}
{% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %}
{% endbtns %}

• 依次为:按钮名 + 链接地址 + 头像

  1. 样式二
1
2
3
{% btns rounded grid5 %}
{% cell 下载源码, https://xaoxuu.com, fas fa-download %}
{% endbtns %}

• 依次为:按钮名 + 链接地址 + 图标名

  1. 样式一
  1. 样式二

7.3 网站卡片 sites

1
2
3
{% sitegroup %}
{% site xaoxuu, url=https://xaoxuu.com, screenshot=https://i.loli.net/2020/08/21/VuSwWZ1xAeUHEBC.jpg, avatar=https://cdn.jsdelivr.net/gh/fomalhaut1998/cdn-assets/avatar/avatar.png, description=简约风格 %}
{% endsitegroup %}

• 参数分别为:网址名+网址链接+网址屏幕截图+网址图标+描述!

8. 其它(基本不用)

8.1 Hexo-tag-map 插件

略,加载很慢的,没意义!

8.2 ghcard标签(github用户信息)

略,加载很慢的,没意义!

8.3 ghbdage标签(徽标)

略,我一般用svg矢量图片代替!

8.4 公式

经常出问题,我一般用图片代替,也省得写公式代码!