重构博客主题时(Compass V2.0 Rebirth)写的一段代码,记录一下...
效果如下:

/**
* Compass Theme For Journey
*
* @abstract
* @version 2.0
* @date 2020/01/03 16:47
* @author Wildlife <admin@lanseyujie.com>
* @link https://www.lanseyujie.com
* @copyright Copyright(c) 2014-2021, lanseyujie.com
*/
function buildToc(contentId, listId) {
let content = document.getElementById(contentId);
if (!content) {
return
}
let tree = content.querySelectorAll('*'),
ele = document.getElementById(listId),
tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
lastLevel = 1,
// 初始化一个有序列表
rootList = document.createElement('ol'),
// 当前的根列表
list = rootList;
rootList.setAttribute('class', 'toc-list');
ele.append(rootList);
tree.forEach(function (node, index) {
// 当前 nodeName 存在于 H 标签列表;H 标签是否存在有效标题
if (tags.indexOf(node.nodeName.toLowerCase()) !== -1 && node.textContent.length > 0) {
// 标记该标题的 id hash 以便跳转
node.setAttribute('id', 'toc-' + index);
// 获取 H 标签的级别
let level = node.nodeName.slice(1),
// 为该 H 标题创建索引 <li level=1><a href="#toc-1">title</a></li>
li = document.createElement('li'),
a = document.createElement('a');
// 标记索引级别
li.setAttribute('data-level', level);
a.setAttribute('href', '#toc-' + index);
a.setAttribute('title', node.textContent)
a.textContent = node.textContent;
li.appendChild(a);
if (index === 0 || lastLevel === level) {
// 将大标题插入根列表
list.appendChild(li);
} else if (lastLevel < level) {
if (list.hasChildNodes()) {
// 当前较上一标题为小标题则创建子列表,并插入索引
let ol = document.createElement('ol');
ol.setAttribute('class', 'toc-list');
ol.appendChild(li);
list.appendChild(ol);
// 更新当前的根列表
list = ol;
} else {
// 上层根列表不存在索引则直接插入
list.appendChild(li);
}
} else if (lastLevel > level) {
// 当前较上一标题为大标题则创建子列表,则获取差几级
let diff = lastLevel - level;
if (diff < 6) {
// 以当前根列表为基准,向父层遍历到所属层级根列表
let tmpList = list;
for (let i = 1; i < 6; i++) {
if (tmpList.parentNode) {
tmpList = tmpList.parentNode;
// 判断是否与该列表内索引层级一致 253,242如果返回
if (tmpList.firstElementChild.getAttribute('data-level') === level || i === diff) {
break;
}
}
}
tmpList.appendChild(li);
list = tmpList;
} else {
// 增强校错
rootList.appendChild(li);
list = rootList;
}
}
lastLevel = level;
}
});
if (rootList.hasChildNodes()) {
ele.parentElement.classList.remove('hidden')
}
} 本文标题:js 生成标题目录树
版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。
上一篇:Kubuntu 高分屏缩放