zhangdocs 1.1.28 → 1.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,6 +32,8 @@ npm install -g zhangdocs
32
32
  npm install zhangdocs
33
33
  ```
34
34
 
35
+ 安装完成后,可以使用 `doc` 命令来操作项目。
36
+
35
37
  ## 🚀 快速开始
36
38
 
37
39
  ### 1. 初始化项目
@@ -39,13 +41,13 @@ npm install zhangdocs
39
41
  在项目目录下运行:
40
42
 
41
43
  ```bash
42
- zhangdocs init
44
+ doc init
43
45
  ```
44
46
 
45
47
  或者指定项目名称:
46
48
 
47
49
  ```bash
48
- zhangdocs init --Create my-docs
50
+ doc init --Create my-docs
49
51
  ```
50
52
 
51
53
  初始化过程会引导你配置项目信息,包括:
@@ -75,7 +77,7 @@ zhangdocs init --Create my-docs
75
77
  ### 3. 构建文档
76
78
 
77
79
  ```bash
78
- zhangdocs build
80
+ doc build
79
81
  ```
80
82
 
81
83
  构建完成后,HTML 文件将生成在 `html/` 目录下,首页 `index.html` 会生成在项目根目录。
@@ -83,7 +85,7 @@ zhangdocs build
83
85
  ### 4. 启动开发服务器
84
86
 
85
87
  ```bash
86
- zhangdocs server
88
+ doc server
87
89
  ```
88
90
 
89
91
  这将启动一个本地服务器,并监听文件变化自动重新构建。
@@ -91,7 +93,7 @@ zhangdocs server
91
93
  ### 5. 监听文件变化
92
94
 
93
95
  ```bash
94
- zhangdocs watch
96
+ doc watch
95
97
  ```
96
98
 
97
99
  监听 `md/` 目录下的文件变化,自动重新构建。
@@ -100,14 +102,14 @@ zhangdocs watch
100
102
 
101
103
  | 命令 | 说明 |
102
104
  |------|------|
103
- | `zhangdocs init` | 初始化项目 |
104
- | `zhangdocs build` | 构建静态页面 |
105
- | `zhangdocs watch` | 监听文件变化并自动构建 |
106
- | `zhangdocs server` | 启动开发服务器(包含 watch 功能) |
107
- | `zhangdocs clean` | 清理构建文件 |
108
- | `zhangdocs deploy` | 部署文档 |
109
- | `zhangdocs theme` | 主题管理 |
110
- | `zhangdocs -V` | 查看版本号 |
105
+ | `doc init` | 初始化项目 |
106
+ | `doc build` | 构建静态页面 |
107
+ | `doc watch` | 监听文件变化并自动构建 |
108
+ | `doc server` | 启动开发服务器(包含 watch 功能) |
109
+ | `doc clean` | 清理构建文件 |
110
+ | `doc deploy` | 部署文档 |
111
+ | `doc theme` | 主题管理 |
112
+ | `doc -V` | 查看版本号 |
111
113
 
112
114
  ## ⚙️ 配置说明
113
115
 
@@ -210,7 +212,7 @@ $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
210
212
 
211
213
  1. 修改现有主题的样式和模板
212
214
  2. 创建新主题
213
- 3. 使用 `zhangdocs theme` 命令管理主题
215
+ 3. 使用 `doc theme` 命令管理主题
214
216
 
215
217
  ## 📝 注意事项
216
218
 
@@ -218,19 +220,3 @@ $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
218
220
  2. **图片路径**:图片应放在 `static/img/` 目录下,在 Markdown 中使用相对路径引用
219
221
  3. **数学公式**:使用 `$...$` 表示行内公式,`$$...$$` 表示块级公式
220
222
  4. **Mermaid 图表**:在代码块中指定语言为 `mermaid`,工具会自动处理特殊字符转义
221
-
222
- ## 📄 许可证
223
-
224
- MIT License
225
-
226
- ## 👤 作者
227
-
228
- kenny wang <wowohoo@qq.com>
229
-
230
- ## 🔗 相关链接
231
-
232
- - [GitHub 仓库](https://github.com/zhangrenyang/zhangdocs.git)
233
-
234
- ---
235
-
236
- **Happy Documenting! 📚**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zhangdocs",
3
- "version": "1.1.28",
3
+ "version": "1.1.31",
4
4
  "description": "Simple document generation tool. Dependence Node.js run.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -53,7 +53,7 @@
53
53
  </div>
54
54
 
55
55
  <!-- 滚动到底部按钮 -->
56
- <button class="scroll-to-bottom" id="scroll-to-bottom" aria-label="滚动到底部" title="滚动到底部">
56
+ <button class="scroll-to-bottom" id="scroll-to-bottom" aria-label="滚动到底部" title="滚动到底部" onclick="(function(){var container=document.querySelector('.markdown-body')||document.querySelector('.warpper')||document.documentElement;container.scrollTop=container.scrollHeight;window.scrollTo(0,document.documentElement.scrollHeight);return false;})();">
57
57
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
58
58
  <path d="M6 9l6 6 6-6"></path>
59
59
  </svg>
@@ -170,12 +170,27 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
170
170
  // Token正确,立即显示内容
171
171
  const mainContainer = document.getElementById('main-container');
172
172
  const menuIcon = document.getElementById('menu-icon');
173
+ const scrollToBottomBtn = document.getElementById('scroll-to-bottom');
173
174
  if (mainContainer) mainContainer.style.display = 'block';
174
175
  if (menuIcon) {
175
176
  menuIcon.style.display = 'flex';
176
177
  // 菜单图标显示后,初始化菜单功能
177
178
  setTimeout(initMenuPopup, 50);
178
179
  }
180
+ // 初始化滚动到底部按钮 - 直接添加 show 类
181
+ if (scrollToBottomBtn) {
182
+ function addShowClass() {
183
+ scrollToBottomBtn.style.display = 'flex';
184
+ scrollToBottomBtn.classList.add('show');
185
+ // 强制设置内联样式,确保显示
186
+ scrollToBottomBtn.style.opacity = '1';
187
+ scrollToBottomBtn.style.visibility = 'visible';
188
+ }
189
+ addShowClass();
190
+ setTimeout(addShowClass, 0);
191
+ setTimeout(addShowClass, 100);
192
+ setTimeout(addShowClass, 300);
193
+ }
179
194
  }
180
195
  })();
181
196
 
@@ -226,6 +241,43 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
226
241
  // 菜单图标显示后,初始化菜单功能
227
242
  setTimeout(initMenuPopup, 50);
228
243
  }
244
+ // 显示内容后,直接显示滚动到底部按钮 - 强制添加 show 类并设置内联样式
245
+ function addShowClass() {
246
+ var scrollToBottomBtn = document.getElementById('scroll-to-bottom');
247
+ if (scrollToBottomBtn) {
248
+ scrollToBottomBtn.style.display = 'flex';
249
+ scrollToBottomBtn.classList.add('show');
250
+ // 强制设置内联样式,确保显示
251
+ scrollToBottomBtn.style.opacity = '1';
252
+ scrollToBottomBtn.style.visibility = 'visible';
253
+ // 确保点击事件已绑定 - 使用多种方式
254
+ if (!scrollToBottomBtn.hasAttribute('data-click-bound')) {
255
+ var clickHandler = function(e) {
256
+ e.preventDefault();
257
+ e.stopPropagation();
258
+ var markdownBody = document.querySelector('.markdown-body');
259
+ var warpper = document.querySelector('.warpper');
260
+ var container = markdownBody || warpper || document.documentElement;
261
+ if (container) {
262
+ container.scrollTop = container.scrollHeight;
263
+ }
264
+ window.scrollTo(0, document.documentElement.scrollHeight);
265
+ return false;
266
+ };
267
+ scrollToBottomBtn.addEventListener('click', clickHandler, true); // 捕获阶段
268
+ scrollToBottomBtn.onclick = clickHandler; // 直接赋值
269
+ scrollToBottomBtn.setAttribute('data-click-bound', 'true');
270
+ }
271
+ }
272
+ }
273
+ // 立即执行
274
+ addShowClass();
275
+ // 多次执行,确保添加成功
276
+ setTimeout(addShowClass, 0);
277
+ setTimeout(addShowClass, 50);
278
+ setTimeout(addShowClass, 100);
279
+ setTimeout(addShowClass, 200);
280
+ setTimeout(addShowClass, 500);
229
281
  }
230
282
 
231
283
  // 隐藏内容
@@ -459,10 +511,9 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
459
511
 
460
512
  // 滚动到底部功能
461
513
  (function() {
462
- var scrollToBottomBtn = document.getElementById('scroll-to-bottom');
463
- if (!scrollToBottomBtn) {
464
- return;
465
- }
514
+ var scrollToBottomBtn = null;
515
+ var mainContainer = null;
516
+ var isInitialized = false;
466
517
 
467
518
  // 检查是否在页面底部
468
519
  function isAtBottom() {
@@ -473,51 +524,215 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
473
524
  return scrollHeight - scrollTop - clientHeight <= 5;
474
525
  }
475
526
 
476
- // 显示/隐藏按钮
477
- function toggleButton() {
478
- if (isAtBottom()) {
479
- scrollToBottomBtn.classList.remove('show');
480
- } else {
527
+ // 显示/隐藏按钮
528
+ function toggleButton() {
529
+ if (!scrollToBottomBtn) {
530
+ return;
531
+ }
532
+
533
+ // 确保按钮可见(如果内容已显示)
534
+ if (mainContainer && mainContainer.style.display !== 'none') {
535
+ scrollToBottomBtn.style.display = 'flex';
536
+
537
+ // 直接添加 show 类,让按钮显示
538
+ // 只有在页面底部时才移除 show 类
539
+ if (isAtBottom()) {
540
+ scrollToBottomBtn.classList.remove('show');
541
+ } else {
542
+ scrollToBottomBtn.classList.add('show');
543
+ }
544
+ } else {
545
+ // 如果内容未显示,确保按钮有 show 类(当内容显示时会自动显示)
546
+ scrollToBottomBtn.classList.add('show');
547
+ }
548
+ }
549
+
550
+ // 初始化函数
551
+ function initScrollToBottom() {
552
+ if (isInitialized) {
553
+ // 如果已初始化,只更新按钮状态
554
+ toggleButton();
555
+ // 即使已初始化,也确保点击事件已绑定
556
+ if (scrollToBottomBtn) {
557
+ scrollToBottomBtn.onclick = function(e) {
558
+ if (e) {
559
+ e.preventDefault();
560
+ e.stopPropagation();
561
+ }
562
+ console.log('按钮被点击了!');
563
+ var markdownBody = document.querySelector('.markdown-body');
564
+ var warpper = document.querySelector('.warpper');
565
+ var container = markdownBody || warpper || document.documentElement;
566
+ if (container && container.scrollTo) {
567
+ container.scrollTop = container.scrollHeight;
568
+ }
569
+ window.scrollTo(0, document.documentElement.scrollHeight);
570
+ return false;
571
+ };
572
+ }
573
+ return;
574
+ }
575
+
576
+ scrollToBottomBtn = document.getElementById('scroll-to-bottom');
577
+ mainContainer = document.getElementById('main-container');
578
+
579
+ if (!scrollToBottomBtn) {
580
+ return;
581
+ }
582
+
583
+ isInitialized = true;
584
+
585
+ // 立即添加 show 类,确保按钮显示
586
+ if (mainContainer && mainContainer.style.display !== 'none') {
587
+ scrollToBottomBtn.style.display = 'flex';
481
588
  scrollToBottomBtn.classList.add('show');
482
589
  }
590
+
591
+ // 滚动到底部 - 找到正确的滚动容器
592
+ function scrollToBottom() {
593
+ // 尝试找到滚动容器
594
+ var markdownBody = document.querySelector('.markdown-body');
595
+ var warpper = document.querySelector('.warpper');
596
+ var container = markdownBody || warpper || document.documentElement;
597
+
598
+ // 滚动容器
599
+ if (container) {
600
+ container.scrollTop = container.scrollHeight;
601
+ }
602
+ // 同时滚动 window(以防万一)
603
+ window.scrollTo(0, document.documentElement.scrollHeight);
604
+ }
605
+
606
+ // 绑定点击事件 - 使用多种方式确保事件能触发
607
+ var clickHandler = function(e) {
608
+ if (e) {
609
+ e.preventDefault();
610
+ e.stopPropagation();
611
+ }
612
+ // 找到滚动容器并滚动
613
+ var markdownBody = document.querySelector('.markdown-body');
614
+ var warpper = document.querySelector('.warpper');
615
+ var container = markdownBody || warpper || document.documentElement;
616
+
617
+ if (container) {
618
+ container.scrollTop = container.scrollHeight;
619
+ }
620
+ // 同时滚动 window
621
+ window.scrollTo(0, document.documentElement.scrollHeight);
622
+ return false;
623
+ };
624
+ // 先移除可能存在的旧监听器
625
+ scrollToBottomBtn.removeEventListener('click', clickHandler);
626
+ // 添加新的监听器 - 使用捕获阶段
627
+ scrollToBottomBtn.addEventListener('click', clickHandler, true);
628
+ // 同时使用 onclick 属性作为备用
629
+ scrollToBottomBtn.onclick = clickHandler;
630
+
631
+ // 监听滚动事件
632
+ var scrollTimer = null;
633
+ window.addEventListener('scroll', function() {
634
+ // 使用节流,减少频繁检查
635
+ if (scrollTimer) {
636
+ clearTimeout(scrollTimer);
637
+ }
638
+ scrollTimer = setTimeout(toggleButton, 100);
639
+ }, { passive: true });
640
+
641
+ // 初始检查(多次检查,确保页面渲染完成)
642
+ // 直接添加 show 类,确保按钮显示
643
+ if (mainContainer && mainContainer.style.display !== 'none') {
644
+ scrollToBottomBtn.style.display = 'flex';
645
+ scrollToBottomBtn.classList.add('show');
646
+ }
647
+ toggleButton();
648
+ setTimeout(toggleButton, 100);
649
+ setTimeout(toggleButton, 300);
650
+ setTimeout(toggleButton, 500);
651
+ setTimeout(toggleButton, 1000);
652
+
653
+ // 监听内容变化(处理动态加载的内容)
654
+ var observer = new MutationObserver(function() {
655
+ setTimeout(toggleButton, 100);
656
+ });
657
+
658
+ observer.observe(document.body, {
659
+ childList: true,
660
+ subtree: true
661
+ });
483
662
  }
484
663
 
485
- // 滚动到底部
486
- function scrollToBottom() {
487
- window.scrollTo({
488
- top: document.documentElement.scrollHeight,
489
- behavior: 'smooth'
490
- });
664
+ // 立即尝试初始化
665
+ initScrollToBottom();
666
+
667
+ // DOM加载完成后初始化
668
+ if (document.readyState === 'loading') {
669
+ document.addEventListener('DOMContentLoaded', initScrollToBottom);
670
+ } else {
671
+ setTimeout(initScrollToBottom, 100);
491
672
  }
492
673
 
493
- // 绑定点击事件
494
- scrollToBottomBtn.addEventListener('click', function(e) {
495
- e.preventDefault();
496
- scrollToBottom();
497
- });
674
+ // 延迟初始化(处理动态显示的情况)
675
+ setTimeout(initScrollToBottom, 500);
676
+ setTimeout(initScrollToBottom, 1000);
677
+ setTimeout(initScrollToBottom, 2000);
498
678
 
499
- // 监听滚动事件
500
- var scrollTimer = null;
501
- window.addEventListener('scroll', function() {
502
- // 使用节流,减少频繁检查
503
- if (scrollTimer) {
504
- clearTimeout(scrollTimer);
679
+ // 强制添加 show 类 - 不依赖任何条件
680
+ function forceShowButton() {
681
+ var btn = document.getElementById('scroll-to-bottom');
682
+ var container = document.getElementById('main-container');
683
+ if (btn && container && container.style.display !== 'none') {
684
+ btn.style.display = 'flex';
685
+ btn.classList.add('show');
686
+ // 确保点击事件已绑定
687
+ if (!btn.hasAttribute('data-click-bound')) {
688
+ btn.addEventListener('click', function(e) {
689
+ e.preventDefault();
690
+ e.stopPropagation();
691
+ var markdownBody = document.querySelector('.markdown-body');
692
+ var warpper = document.querySelector('.warpper');
693
+ var container = markdownBody || warpper || document.documentElement;
694
+ if (container && container.scrollTo) {
695
+ container.scrollTop = container.scrollHeight;
696
+ }
697
+ window.scrollTo(0, document.documentElement.scrollHeight);
698
+ });
699
+ btn.setAttribute('data-click-bound', 'true');
700
+ }
505
701
  }
506
- scrollTimer = setTimeout(toggleButton, 100);
507
- }, { passive: true });
702
+ }
508
703
 
509
- // 初始检查
510
- setTimeout(toggleButton, 500);
704
+ // 在多个时机强制添加 show 类
705
+ forceShowButton();
706
+ setTimeout(forceShowButton, 100);
707
+ setTimeout(forceShowButton, 200);
708
+ setTimeout(forceShowButton, 500);
709
+ setTimeout(forceShowButton, 1000);
710
+ setTimeout(forceShowButton, 2000);
511
711
 
512
- // 监听内容变化(处理动态加载的内容)
513
- var observer = new MutationObserver(function() {
514
- setTimeout(toggleButton, 100);
515
- });
712
+ // 监听内容显示事件
713
+ if (document.readyState === 'loading') {
714
+ document.addEventListener('DOMContentLoaded', forceShowButton);
715
+ }
516
716
 
517
- observer.observe(document.body, {
518
- childList: true,
519
- subtree: true
717
+ // 使用 MutationObserver 监听 main-container 的显示状态
718
+ var containerObserver = new MutationObserver(function(mutations) {
719
+ mutations.forEach(function(mutation) {
720
+ if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
721
+ var container = document.getElementById('main-container');
722
+ if (container && container.style.display !== 'none') {
723
+ forceShowButton();
724
+ }
725
+ }
726
+ });
520
727
  });
728
+
729
+ var mainContainer = document.getElementById('main-container');
730
+ if (mainContainer) {
731
+ containerObserver.observe(mainContainer, {
732
+ attributes: true,
733
+ attributeFilter: ['style']
734
+ });
735
+ }
521
736
  })();
522
737
  </script>
523
738
  <% include footer.ejs %>
@@ -516,49 +516,54 @@ table
516
516
 
517
517
  // 滚动到底部按钮
518
518
  .scroll-to-bottom
519
- position: fixed
520
- bottom: 30px
521
- right: 30px
522
- width: 48px
523
- height: 48px
524
- background: #fff
525
- border: 1px solid $border-color
519
+ position: fixed !important
520
+ bottom: 30px !important
521
+ right: 5px !important
522
+ width: 36px !important
523
+ height: 36px !important
524
+ background: transparent
525
+ border: none
526
526
  border-radius: 50%
527
- cursor: pointer
528
- z-index: 999
527
+ cursor: pointer !important
528
+ z-index: 99999 !important
529
529
  display: none
530
530
  align-items: center
531
531
  justify-content: center
532
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15)
533
- transition: all 0.3s ease
532
+ box-shadow: none
533
+ transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.2s ease
534
534
  color: $text-color
535
535
  padding: 0
536
536
  -webkit-tap-highlight-color: transparent
537
+ opacity: 0
538
+ visibility: hidden
539
+ pointer-events: auto
540
+ user-select: none
537
541
 
538
542
  &:hover
539
- background: $primary-color
540
- border-color: $primary-color
541
- color: #fff
542
- transform: translateY(-3px)
543
- box-shadow: 0 4px 12px rgba(74, 144, 226, 0.4)
543
+ background: rgba(74, 144, 226, 0.1)
544
+ color: $primary-color
545
+ transform: translateY(-2px)
544
546
 
545
547
  &:active
546
- transform: translateY(-1px)
547
- box-shadow: 0 2px 6px rgba(74, 144, 226, 0.3)
548
+ transform: translateY(0)
548
549
 
549
550
  svg
550
- width: 20px
551
- height: 20px
551
+ width: 16px
552
+ height: 16px
553
+ pointer-events: none
552
554
 
553
555
  &.show
554
- display: flex
556
+ display: flex !important
557
+ opacity: 1 !important
558
+ visibility: visible !important
559
+ pointer-events: auto !important
555
560
 
556
561
  @media mq-mobile
557
562
  bottom: 20px
558
- right: 20px
559
- width: 44px
560
- height: 44px
563
+ right: 5px
564
+ width: 32px
565
+ height: 32px
561
566
 
562
567
  svg
563
- width: 18px
564
- height: 18px
568
+ width: 14px
569
+ height: 14px