docsify-sidebar-collapse.min.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (factory());
  5. }(this, (function () {
  6. 'use strict';
  7. function styleInject(css, ref) {
  8. if (ref === void 0) ref = {};
  9. var insertAt = ref.insertAt;
  10. if (!css || typeof document === 'undefined') { return; }
  11. var head = document.head || document.getElementsByTagName('head')[0];
  12. var style = document.createElement('style');
  13. style.type = 'text/css';
  14. if (insertAt === 'top') {
  15. if (head.firstChild) {
  16. head.insertBefore(style, head.firstChild);
  17. } else {
  18. head.appendChild(style);
  19. }
  20. } else {
  21. head.appendChild(style);
  22. }
  23. if (style.styleSheet) {
  24. style.styleSheet.cssText = css;
  25. } else {
  26. style.appendChild(document.createTextNode(css));
  27. }
  28. }
  29. var css = ".sidebar-nav > ul > li ul {\n display: none;\n}\n\n.app-sub-sidebar {\n display: none;\n}\n\n.app-sub-sidebar.open {\n display: block;\n}\n\n.sidebar-nav .open > ul:not(.app-sub-sidebar),\n.sidebar-nav .active:not(.collapse) > ul {\n display: block;\n}\n\n/* 抖动 */\n.sidebar-nav li.open:not(.collapse) > ul {\n display: block;\n}\n\n.active + ul.app-sub-sidebar {\n display: block;\n}\n";
  30. styleInject(css);
  31. function sidebarCollapsePlugin(hook, vm) {
  32. hook.doneEach(function (html, next) {
  33. var activeNode = getActiveNode();
  34. openActiveToRoot(activeNode);
  35. addFolderFileClass();
  36. addLevelClass();
  37. syncScrollTop(activeNode);
  38. next(html);
  39. });
  40. hook.ready(function () {
  41. document.querySelector('.sidebar-nav').addEventListener('click', handleMenuClick);
  42. });
  43. }
  44. function init() {
  45. document.addEventListener('scroll', scrollSyncMenuStatus);
  46. }
  47. var lastTop; // 侧边栏滚动状态
  48. function syncScrollTop(activeNode) {
  49. if (activeNode && lastTop != undefined) {
  50. var curTop = activeNode.getBoundingClientRect().top;
  51. document.querySelector('.sidebar').scrollBy(0, curTop - lastTop);
  52. }
  53. }
  54. function scrollSyncMenuStatus() {
  55. requestAnimationFrame(function () {
  56. var el = document.querySelector('.app-sub-sidebar > .active');
  57. if (el) {
  58. el.parentNode.parentNode.querySelectorAll('.app-sub-sidebar').forEach(function (dom) {
  59. return dom.classList.remove('open');
  60. });
  61. while (el.parentNode.classList.contains('app-sub-sidebar')) {
  62. if (el.parentNode.classList.contains('open')) {
  63. break;
  64. } else {
  65. el.parentNode.classList.add('open');
  66. el = el.parentNode;
  67. }
  68. }
  69. }
  70. });
  71. }
  72. function handleMenuClick(e) {
  73. lastTop = e.target.getBoundingClientRect().top;
  74. var newActiveNode = findTagParent(e.target, 'LI', 2);
  75. if (!newActiveNode) return;
  76. if (newActiveNode.classList.contains('open')) {
  77. newActiveNode.classList.remove('open'); // docsify 默认行为会操作 collapse,我们异步之后修补
  78. setTimeout(function () {
  79. newActiveNode.classList.add('collapse');
  80. }, 0);
  81. } else {
  82. removeOpenToRoot(getActiveNode());
  83. openActiveToRoot(newActiveNode); // docsify 默认行为会操作 collapse,我们异步之后修补
  84. setTimeout(function () {
  85. newActiveNode.classList.remove('collapse');
  86. }, 0);
  87. }
  88. syncScrollTop(newActiveNode);
  89. }
  90. function getActiveNode() {
  91. var node = document.querySelector('.sidebar-nav .active');
  92. if (!node) {
  93. var curLink = document.querySelector(".sidebar-nav a[href=\"".concat(decodeURIComponent(location.hash).replace(/ /gi, '%20'), "\"]"));
  94. node = findTagParent(curLink, 'LI', 2);
  95. if (node) {
  96. node.classList.add('active');
  97. }
  98. }
  99. return node;
  100. }
  101. function openActiveToRoot(node) {
  102. if (node) {
  103. node.classList.add('open', 'active');
  104. while (node && node.className !== 'sidebar-nav' && node.parentNode) {
  105. if (node.parentNode.tagName === 'LI' || node.parentNode.className === 'app-sub-sidebar') {
  106. node.parentNode.classList.add('open');
  107. }
  108. node = node.parentNode;
  109. }
  110. }
  111. }
  112. function removeOpenToRoot(node) {
  113. if (node) {
  114. node.classList.remove('open', 'active');
  115. while (node && node.className !== 'sidebar-nav' && node.parentNode) {
  116. if (node.parentNode.tagName === 'LI' || node.parentNode.className === 'app-sub-sidebar') {
  117. node.parentNode.classList.remove('open');
  118. }
  119. node = node.parentNode;
  120. }
  121. }
  122. }
  123. function findTagParent(curNode, tagName, level) {
  124. if (curNode && curNode.tagName === tagName) return curNode;
  125. var l = 0;
  126. while (curNode) {
  127. l++;
  128. if (l > level) return;
  129. if (curNode.parentNode.tagName === tagName) {
  130. return curNode.parentNode;
  131. }
  132. curNode = curNode.parentNode;
  133. }
  134. }
  135. function addFolderFileClass() {
  136. document.querySelectorAll('.sidebar-nav li').forEach(function (li) {
  137. if (li.querySelector('ul:not(.app-sub-sidebar)')) {
  138. var plus = document.createElement('i')
  139. plus.className = 'plus'
  140. li.prepend(plus)
  141. li.classList.add('folder');
  142. } else {
  143. li.classList.add('file');
  144. }
  145. });
  146. }
  147. function addLevelClass() {
  148. function find(root, level) {
  149. root.childNodes && root.childNodes.forEach(function (child) {
  150. if (child.classList && child.classList.contains('folder')) {
  151. child.classList.add("level-".concat(level));
  152. if (window.$docsify && window.$docsify.sidebarDisplayLevel && typeof window.$docsify.sidebarDisplayLevel === 'number' && level <= window.$docsify.sidebarDisplayLevel) {
  153. child.classList.add('open');
  154. }
  155. if (child && child.childNodes.length > 1) {
  156. find(child.childNodes[1], level + 1);
  157. }
  158. }
  159. });
  160. }
  161. find(document.querySelector('.sidebar-nav > ul'), 1);
  162. }
  163. init();
  164. var css$1 = "@media screen and (max-width: 768px) {\n /* 移动端适配 */\n .markdown-section {\n max-width: none;\n padding: 16px;\n }\n /* 改变原来按钮热区大小 */\n .sidebar-toggle {\n padding: 0 0 10px 10px;\n }\n /* my pin */\n .sidebar-pin {\n appearance: none;\n outline: none;\n position: fixed;\n bottom: 0;\n border: none;\n width: 40px;\n height: 40px;\n background: transparent;\n }\n}\n";
  165. styleInject(css$1);
  166. var PIN = 'DOCSIFY_SIDEBAR_PIN_FLAG';
  167. function init$1() {
  168. // 响应式尺寸 @media screen and (max-width: 768px)
  169. if (document.documentElement.clientWidth > 768) return;
  170. localStorage.setItem(PIN, false); // 添加覆盖标签
  171. var btn = document.createElement('button');
  172. btn.classList.add('sidebar-pin');
  173. btn.onclick = togglePin;
  174. document.body.append(btn);
  175. window.addEventListener('load', function () {
  176. var content = document.querySelector('.content'); // 点击内容区域收起侧边栏
  177. document.body.onclick = content.onclick = function (e) {
  178. if (e.target === document.body || e.currentTarget === content) {
  179. if (localStorage.getItem(PIN) === 'true') {
  180. togglePin();
  181. }
  182. }
  183. };
  184. });
  185. }
  186. function togglePin() {
  187. var pin = localStorage.getItem(PIN);
  188. pin = pin === 'true';
  189. localStorage.setItem(PIN, !pin);
  190. if (pin) {
  191. document.querySelector('.sidebar').style.transform = 'translateX(0)';
  192. document.querySelector('.content').style.transform = 'translateX(0)';
  193. } else {
  194. document.querySelector('.sidebar').style.transform = 'translateX(300px)';
  195. document.querySelector('.content').style.transform = 'translateX(300px)';
  196. }
  197. }
  198. init$1();
  199. function install() {
  200. if (!window.$docsify) {
  201. console.error('这是一个docsify插件,请先引用docsify库!');
  202. } else {
  203. for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
  204. plugins[_key] = arguments[_key];
  205. }
  206. $docsify.plugins = plugins.concat($docsify.plugins || []);
  207. }
  208. }
  209. install(sidebarCollapsePlugin);
  210. })));