// richTextElement为富文本所在dom
const hTags = richTextElement.querySelectorAll('h1, h2, h3, h4, h5, h6');
const htmlHTags = [];
hTags.forEach((item, index) => {
// eslint-disable-next-line no-param-reassign
item.id = `fileHeading${parseInt(item.nodeName.split('H')[1], 10)}-${index + 1}`;
htmlHTags.push({
text: item.innerText,
level: parseInt(item.nodeName.split('H')[1], 10),
id: index + 1,
});
});
handleRichLinkList(htmlHTags);
// 处理富文本的目录
const handleRichLinkList = useCallback((list) => {
const anchorArr = [];
handleAnchor(list, anchorArr);
}, []);
// 将平级目录处理成嵌套级
const handleAnchor = useCallback((list = [], anchorArr) => {
list.forEach((item) => {
if (item.id === 1) {
// 第一个标题直接push
anchorArr.push(item);
} else {
// 获取当前目录中最后一个标题
let lastItem = last(anchorArr);
// 标题为最后一个标题的children
if (item.level > lastItem.level) {
for (let i = lastItem.level + 1; i <= 6; i++) {
const { children } = lastItem;
if (!children) {
// 不存在子标题
lastItem.children = [item];
break;
}
// 重置lastItem为children的最后一个item
lastItem = last(children);
if (item.level <= lastItem.level) {
// 视为与children同级
// 若仍为children中的子级,则lastItem为children,比较children下有无children
children.push(item);
break;
}
}
} else {
// 同级
anchorArr.push(item);
}
}
});
}, []);
效果如图