简单的生成文章内容目录(vue可用)
在富文本辑编器里面写文章时,我们通常会使用h1-h6标签来定义章节标题。在用户端显示时希望展示目录结构。如图;这里生成目录结构可以借助第三方插件来实现,但某些情况下不希望引用太多的第三方资源就需要自己实现一个。核心思路:拿到所有的h标签的节点集合,这个集合就是内容(平级)的目录,我们只需要将平级目录根据标签的(level 等级)/大小,设定一个缩进的长度乘标签大小就可生成有层次的目录结果。为了能使
·
在富文本辑编器里面写文章时,我们通常会使用h1-h6标签来定义章节标题。在用户端显示时希望展示目录结构。如图;
这里生成目录结构可以借助第三方插件来实现,但某些情况下不希望引用太多的第三方资源就需要自己实现一个。
核心思路:拿到所有的h标签的节点集合,这个集合就是内容(平级)的目录,我们只需要将平级目录根据标签的(level 等级)/大小,设定一个缩进的长度乘标签大小就可生成有层次的目录结果。为了能使用使用瞄点定位,故每个节点设定一个id
核心处理代码
//拿到文章内容的节点
let parent = document.getElementById("previewer")
//拿到文章里面的h1-h6标签
let doms = parent.querySelectorAll('h1,h2,h3,h4,h5,h6');
let hEles = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
//结果集
let catalogue = [];
let index = 0;
if(doms.length>0){
doms.forEach(element => {
var nodetext = element.innerHTML.replace(/<\/?[^>]+>/g, "");
nodetext = nodetext );
let name = element.nodeName.toLowerCase();
if (hEles.includes(name)) {
index++;
let id = `catalogue_${index}`;
//为当前节点添加id,方便使用瞄点定位
element.setAttribute("id", id)
let level = name.replace("h", "");
catalogue.push({ id: id, key: name, title: nodetext, level: Number(level) });
}
});
以下是vue版本的实现
let data = reactive({ news: {}, loading: true, catalogue: [] })
const { proxy } = getCurrentInstance()
let id = proxy.$root.$router.currentRoute.value.params.id
onMounted(() => {
proxy.$http.get(`/api/blog/news/${id}`).then((res) => {
data.news = res;
document.title = res.title;
});
})
nextTick(() => {
setTimeout(() => {
//等待dom 加载完成
uParse("#previewer", {
rootPath: 'https://cdn.jsdelivr.net/gh/t-jian/static/theme/ueditor-1.4.3/',
liiconpath: 'https://cdn.jsdelivr.net/gh/t-jian/static/theme/ueditor-1.4.3/listicon/',
});
setTimeout(() => {
//防止闪烁
data.loading = false;
//目录导航
let parent = document.getElementById("previewer")
let doms = parent.querySelectorAll('h1,h2,h3,h4,h5,h6');
let hEles = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
let catalogue = [];
let index = 0;
if(doms.length>0){
doms.forEach(element => {
var nodetext = element.innerHTML.replace(/<\/?[^>]+>/g, "");
nodetext = nodetext.replace(/ /ig, "");
let name = element.nodeName.toLowerCase();
if (hEles.includes(name)) {
index++;
let id = `catalogue_${index}`;
element.setAttribute("id", id)
let level = name.replace("h", "");
catalogue.push({ id: id, key: name, title: nodetext, level: Number(level) });
}
});
data.catalogue = catalogue;
}
}, 100);
}, 300);
<div class="item-card rt-panel">
<div class="nav-title">文章导航</div>
<ul class="catalogue-box">
<li v-for="item in catalogue" :key="item">
<a :href="'#'+item.id"><span :style="'margin-left:'+(4*item.level)+'px;'">{{item.title}}</span> </a>
</li>
</ul>
</div>
更多推荐
已为社区贡献2条内容
所有评论(0)