zhangdocs 1.1.29 → 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.29",
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>
@@ -177,20 +177,19 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
177
177
  // 菜单图标显示后,初始化菜单功能
178
178
  setTimeout(initMenuPopup, 50);
179
179
  }
180
- // 初始化滚动到底部按钮
180
+ // 初始化滚动到底部按钮 - 直接添加 show 类
181
181
  if (scrollToBottomBtn) {
182
- setTimeout(function() {
182
+ function addShowClass() {
183
183
  scrollToBottomBtn.style.display = 'flex';
184
- // 检查是否需要显示按钮
185
- setTimeout(function() {
186
- var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
187
- var scrollHeight = document.documentElement.scrollHeight;
188
- var clientHeight = document.documentElement.clientHeight;
189
- if (scrollHeight - scrollTop - clientHeight > 5) {
190
- scrollToBottomBtn.classList.add('show');
191
- }
192
- }, 200);
193
- }, 100);
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);
194
193
  }
195
194
  }
196
195
  })();
@@ -242,22 +241,43 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
242
241
  // 菜单图标显示后,初始化菜单功能
243
242
  setTimeout(initMenuPopup, 50);
244
243
  }
245
- // 显示内容后,初始化滚动到底部按钮
246
- setTimeout(function() {
244
+ // 显示内容后,直接显示滚动到底部按钮 - 强制添加 show 类并设置内联样式
245
+ function addShowClass() {
247
246
  var scrollToBottomBtn = document.getElementById('scroll-to-bottom');
248
247
  if (scrollToBottomBtn) {
249
248
  scrollToBottomBtn.style.display = 'flex';
250
- // 检查是否需要显示按钮
251
- setTimeout(function() {
252
- var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
253
- var scrollHeight = document.documentElement.scrollHeight;
254
- var clientHeight = document.documentElement.clientHeight;
255
- if (scrollHeight - scrollTop - clientHeight > 5) {
256
- scrollToBottomBtn.classList.add('show');
257
- }
258
- }, 100);
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
+ }
259
271
  }
260
- }, 100);
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);
261
281
  }
262
282
 
263
283
  // 隐藏内容
@@ -491,54 +511,122 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
491
511
 
492
512
  // 滚动到底部功能
493
513
  (function() {
514
+ var scrollToBottomBtn = null;
515
+ var mainContainer = null;
516
+ var isInitialized = false;
517
+
518
+ // 检查是否在页面底部
519
+ function isAtBottom() {
520
+ var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
521
+ var scrollHeight = document.documentElement.scrollHeight;
522
+ var clientHeight = document.documentElement.clientHeight;
523
+ // 允许5px的误差
524
+ return scrollHeight - scrollTop - clientHeight <= 5;
525
+ }
526
+
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
+ // 初始化函数
494
551
  function initScrollToBottom() {
495
- var scrollToBottomBtn = document.getElementById('scroll-to-bottom');
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
+
496
579
  if (!scrollToBottomBtn) {
497
580
  return;
498
581
  }
499
582
 
500
- // 确保按钮可见(如果内容已显示)
501
- var mainContainer = document.getElementById('main-container');
583
+ isInitialized = true;
584
+
585
+ // 立即添加 show 类,确保按钮显示
502
586
  if (mainContainer && mainContainer.style.display !== 'none') {
503
587
  scrollToBottomBtn.style.display = 'flex';
588
+ scrollToBottomBtn.classList.add('show');
504
589
  }
505
590
 
506
- // 检查是否在页面底部
507
- function isAtBottom() {
508
- var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
509
- var scrollHeight = document.documentElement.scrollHeight;
510
- var clientHeight = document.documentElement.clientHeight;
511
- // 允许5px的误差
512
- return scrollHeight - scrollTop - clientHeight <= 5;
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);
513
604
  }
514
605
 
515
- // 显示/隐藏按钮
516
- function toggleButton() {
517
- // 确保按钮可见
518
- if (mainContainer && mainContainer.style.display !== 'none') {
519
- scrollToBottomBtn.style.display = 'flex';
606
+ // 绑定点击事件 - 使用多种方式确保事件能触发
607
+ var clickHandler = function(e) {
608
+ if (e) {
609
+ e.preventDefault();
610
+ e.stopPropagation();
520
611
  }
612
+ // 找到滚动容器并滚动
613
+ var markdownBody = document.querySelector('.markdown-body');
614
+ var warpper = document.querySelector('.warpper');
615
+ var container = markdownBody || warpper || document.documentElement;
521
616
 
522
- if (isAtBottom()) {
523
- scrollToBottomBtn.classList.remove('show');
524
- } else {
525
- scrollToBottomBtn.classList.add('show');
617
+ if (container) {
618
+ container.scrollTop = container.scrollHeight;
526
619
  }
527
- }
528
-
529
- // 滚动到底部
530
- function scrollToBottom() {
531
- window.scrollTo({
532
- top: document.documentElement.scrollHeight,
533
- behavior: 'smooth'
534
- });
535
- }
536
-
537
- // 绑定点击事件
538
- scrollToBottomBtn.addEventListener('click', function(e) {
539
- e.preventDefault();
540
- scrollToBottom();
541
- });
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;
542
630
 
543
631
  // 监听滚动事件
544
632
  var scrollTimer = null;
@@ -550,8 +638,17 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
550
638
  scrollTimer = setTimeout(toggleButton, 100);
551
639
  }, { passive: true });
552
640
 
553
- // 初始检查
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);
554
649
  setTimeout(toggleButton, 300);
650
+ setTimeout(toggleButton, 500);
651
+ setTimeout(toggleButton, 1000);
555
652
 
556
653
  // 监听内容变化(处理动态加载的内容)
557
654
  var observer = new MutationObserver(function() {
@@ -577,6 +674,65 @@ style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background:
577
674
  // 延迟初始化(处理动态显示的情况)
578
675
  setTimeout(initScrollToBottom, 500);
579
676
  setTimeout(initScrollToBottom, 1000);
677
+ setTimeout(initScrollToBottom, 2000);
678
+
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
+ }
701
+ }
702
+ }
703
+
704
+ // 在多个时机强制添加 show 类
705
+ forceShowButton();
706
+ setTimeout(forceShowButton, 100);
707
+ setTimeout(forceShowButton, 200);
708
+ setTimeout(forceShowButton, 500);
709
+ setTimeout(forceShowButton, 1000);
710
+ setTimeout(forceShowButton, 2000);
711
+
712
+ // 监听内容显示事件
713
+ if (document.readyState === 'loading') {
714
+ document.addEventListener('DOMContentLoaded', forceShowButton);
715
+ }
716
+
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
+ });
727
+ });
728
+
729
+ var mainContainer = document.getElementById('main-container');
730
+ if (mainContainer) {
731
+ containerObserver.observe(mainContainer, {
732
+ attributes: true,
733
+ attributeFilter: ['style']
734
+ });
735
+ }
580
736
  })();
581
737
  </script>
582
738
  <% include footer.ejs %>
@@ -516,53 +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
537
  opacity: 0
538
538
  visibility: hidden
539
+ pointer-events: auto
540
+ user-select: none
539
541
 
540
542
  &:hover
541
- background: $primary-color
542
- border-color: $primary-color
543
- color: #fff
544
- transform: translateY(-3px)
545
- 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)
546
546
 
547
547
  &:active
548
- transform: translateY(-1px)
549
- box-shadow: 0 2px 6px rgba(74, 144, 226, 0.3)
548
+ transform: translateY(0)
550
549
 
551
550
  svg
552
- width: 20px
553
- height: 20px
551
+ width: 16px
552
+ height: 16px
553
+ pointer-events: none
554
554
 
555
555
  &.show
556
- display: flex
557
- opacity: 1
558
- visibility: visible
556
+ display: flex !important
557
+ opacity: 1 !important
558
+ visibility: visible !important
559
+ pointer-events: auto !important
559
560
 
560
561
  @media mq-mobile
561
562
  bottom: 20px
562
- right: 20px
563
- width: 44px
564
- height: 44px
563
+ right: 5px
564
+ width: 32px
565
+ height: 32px
565
566
 
566
567
  svg
567
- width: 18px
568
- height: 18px
568
+ width: 14px
569
+ height: 14px