Ver código fonte

feat(docs): Highlight current section in table of contents

Michael Bromley 7 anos atrás
pai
commit
ddaee4fd71
3 arquivos alterados com 52 adições e 1 exclusões
  1. 48 0
      docs/assets/scripts/main.ts
  2. 3 0
      docs/assets/styles/main.scss
  3. 1 1
      docs/tsconfig.json

+ 48 - 0
docs/assets/scripts/main.ts

@@ -10,4 +10,52 @@ document.addEventListener('DOMContentLoaded', () => {
             }
             }
         });
         });
     }
     }
+
+    highlightToc();
 }, false);
 }, false);
+
+/**
+ * Highlight the current section in the table of contents when scrolling.
+ */
+function highlightToc() {
+    const toc = document.querySelector('#TableOfContents') as HTMLElement;
+    const article = document.querySelector('article');
+    if (toc && article) {
+        const headers: HTMLHeadingElement[] = Array.from(article.querySelectorAll('h1[id],h2[id],h3[id]'));
+
+        window.addEventListener('scroll', (e) => {
+            highlightCurrentSection(headers);
+        });
+        highlightCurrentSection(headers);
+    }
+
+    function highlightCurrentSection(headers: HTMLElement[]) {
+        const locationHash = location.hash;
+        Array.from(toc.querySelectorAll('.active')).forEach(el => el.classList.remove('active'));
+
+        // tslint:disable:prefer-for-of
+        for (let i = 0; i < headers.length; i++) {
+            const header = headers[i];
+            const nextHeader = headers[i + 1];
+            const id = header.getAttribute('id') as string;
+            if (!nextHeader || (nextHeader && (window.scrollY + window.innerHeight - 200) < nextHeader.offsetTop)) {
+                highlightItem(id);
+                return;
+            }
+
+            const isCurrentTarget = `#${id}` === locationHash;
+            const currentTargetOffset = isCurrentTarget ? 90 : 0;
+            if ((header.offsetTop + currentTargetOffset) >= window.scrollY) {
+                highlightItem(id);
+                return;
+            }
+        }
+    }
+
+    function highlightItem(id: string) {
+        const tocItem = toc.querySelector(`[href="#${id}"]`);
+        if (tocItem) {
+            tocItem.classList.add('active');
+        }
+    }
+}

+ 3 - 0
docs/assets/styles/main.scss

@@ -134,6 +134,9 @@ ul.pagination {
     nav > ul > li {
     nav > ul > li {
         margin: 0;
         margin: 0;
     }
     }
+    a.active {
+        font-weight: bold;
+    }
 }
 }
 
 
 .book-git-footer {
 .book-git-footer {

+ 1 - 1
docs/tsconfig.json

@@ -4,7 +4,7 @@
     "module": "None",
     "module": "None",
     "lib": [
     "lib": [
       "es2017",
       "es2017",
-      "dom",
+      "dom"
     ],
     ],
     "target": "es5",
     "target": "es5",
     "outFile": "static/main.js"
     "outFile": "static/main.js"