摘要:本人為菜鳥,有問題請指正目錄最近用搭建個人博客在制作文章顯示頁面時,需要在前端頁面生成。剛開始很糾結如何生成有層級結構的代碼,最后發現可以使用設計模式中的組合模式來完成這一功能。具體點就是將節點看作葉子節點,節點看錯作容器。
本人為Javascript菜鳥,有問題請指正...
TOC目錄最近用Flask搭建個人博客在制作文章顯示頁面時,需要在前端頁面生成TOC。就打算自己寫一個JavaScript腳本。
需要生成的目標HTML代碼如下:
在看了JavaScript權威指南這本書后,發現其中雖然有例子生成TOC,但是并沒有顯示層級。不過,其中有一個記錄TOC各個錨點序號的好方法:
# 使用一個數組報錯分析算法邏輯的level為1 var level = parseInt(header.tagName.charAt(1)); # 當處理一個標簽后,計算加1 sectionNumbers[level-1]++ # 然后去當前序號 比如序號為2.1.1 sectionNumber = sectionNumbers.slice(0,level).join(".")
吹牛B之前需要打草稿,寫代碼之前也如此。
剛開始很糾結如何生成有層級結構的HTML代碼,最后發現可以使用設計模式中的組合模式來完成這一功能。具體點就是將li節點看作葉子節點,ul節點看錯作容器。那么就有一下限制:
只有ul節點可以插入li節點
li節點需要插入子節點,就需要創建一個ul子節點,讓子節點去插入li節點
ul與它的li子節點level相同
如果當前節點需要處理一個header,就需要作出以下判斷:
判斷自己為ul節點還是li節點
如果為ul節點,且待處理的header的level與自己相同,那么就直接生成一個li節點并插入;如果待處理的header的level比自己大,那么就找到子節點,交給子節點去處理。
如果為li節點,且待處理的header的level比自己大,那么就取li節點的ul節點,交給ul節點去處理
一直向下去處理header,直到插入成功
代碼實現為了盡量減少代碼的污染,使用Fucntion.call(args)方式了動態的給節點添加屬性:
var sectionNumbers = [0, 0, 0, 0, 0, 0]; function Toc() { this.headers = $(this).find(":header"); var ul = document.createElement("ul"); this.toc = TocObj.call(ul, 1); for(var i = 0; i < this.headers.length; i++) { // if(i > 1) break; this.toc.add(this.headers[i]); } console.log(this.toc); } function TocObj(level) { this.level = level; this.num = 0; this.add = function(header) { var flag = this.tagName == "UL"; // ul節點和li節點處理header的方式不通過 var level = parseInt(header.tagName.charAt(1)); if(flag) { // 只有ul節點才能插入li if(this.num == 0 || level == this.level) { var link = document.createElement("a"); link.href = ""; link.innerHTML = header.innerHTML; sectionNumbers[level-1]++; for(var i = level; i < sectionNumbers.length; i++) sectionNumbers[i] = 0; link.href = "#TOC" + sectionNumbers.slice(0, level).join("."); var li = document.createElement("li"); li.insertBefore(link, li.firstChild); this.num++; this.appendChild(TocObj.call(li, level)); } else if(level > this.level){ if(this.num == 0) { throw new Error("level error 1"); } var lastChild = this.lastChild; lastChild.add(header); // 讓ul節點的li節點去處理header } } else { // li節點讓它的ul子節點去插入li if(level == this.level) { throw new Error("level error 2"); } else if(level > this.level){ if(this.num == 0) { // 沒有ul子節點,就創建一個 var ul = document.createElement("ul"); this.appendChild(ul); this.num++; TocObj.call(ul, level).add(header); // 注意設置level } else { var lastChild = this.lastChild; lastChild.add(header); //讓ul節點去處理這個header } } } } return this; } var toc = document.getElementsByClassName("post")[0]; Toc.call(toc);效果展示
對于有以下結構的HTML代碼:
標題1
標題1.1
標題1.2
標題2
標題2.1
標題2.1.1
標題3
標題4
標題5
輸出結構如下:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87713.html
摘要:使用可以快速為你的頁面生成目錄的結構,擁有較強的可定制性,并且并不會擅自為你做太多的事情,以便你更容易地把應用到你的項目中。 引言 為頁面中的標題元素建立目錄索引,這是一個不起眼卻很實用的功能,特別是對于那些含有篇幅很長的文章的頁面,擁有一個目錄可以讓讀者對文章的結構一目了然,更重要的是,讀者可以很輕松地在文章的各個章節之間來回快速跳轉,極大地提高了用戶體驗。 toc.js 使用 to...
摘要:在作用域頂部聲明變量,避免變量聲明和賦值引起的相關問題。分號語句結束一定要加分號類型轉換在語句的開始執行類型轉換字符串對數字使用并且總是帶上類型轉換的基數布爾值命名約定避免單個字符名,讓你的變量名有描述意義。 原文:https://github.com/airbnb/javascript JavaScript規范 內容列表 類型 對象 數組 字符串 函數 屬性 變量 條件表達式和等號...
摘要:文章首發自我的個人網站前言學也有一段時間了網上也有不少官方文檔的中文翻譯版但是似乎只有中文網站文檔一直是最新的奈何并沒有供直接下載是在是不太方便為了方便閱讀以及方便后續文檔更新決定用寫一個爬蟲將網頁下載下來保持為最后完成結果如下是的沒錯 文章首發自我的 個人網站-Leetaos Blog 前言 學 Rust 也有一段時間了,網上也有不少官方文檔的中文翻譯版,但是似乎只有 [Rust中...
摘要:原文鏈接的博客制作目錄索引這種東西當然是放在前端方便。選擇放在后端一是為了了解后端生態,掌握更多后端技術二是因為公司實行前后端分離的方式開發,睪貴的后端經常啥也不做處理就返回一個數據甚至有時時間戳都不處理,對此有些無語。 原文鏈接:Bougie的博客 制作目錄索引這種東西當然是放在前端方便。選擇放在后端一是為了了解Node后端生態,掌握更多后端技術;二是因為公司實行前后端分離的方式開發...
摘要:文件一鍵生成目錄支持優雅的寫法支持多次生成支持重復標題的生成支持特殊字符的過濾支持指定不同的文件編碼支持文件夾的文件批量處理可指定是否包含子文件夾文件支持是否寫入文件,可返回目錄的內容,便于用戶自行處理環境依賴請確保設置正確。 業務需要 在編寫 github 項目時,有時候會編寫各種 README.md 等 markdown 文件,但是 github 默認是沒有目錄的。 于是就自己想辦...
閱讀 5075·2023-04-25 19:30
閱讀 2173·2023-04-25 15:09
閱讀 2618·2021-11-16 11:45
閱讀 2171·2021-11-15 18:07
閱讀 1458·2021-11-11 17:22
閱讀 2115·2021-11-04 16:06
閱讀 3576·2021-10-20 13:47
閱讀 3036·2021-09-22 16:03