摘抄改进 JS 生成文章目录树 js动态树目录 锚链接文本目录
<div class="sider-list-1">
<div id="navDivId">nav</div>
// 目录树容器
</div>
<style>
li[catalog] {
padding-left: calc(var(--level) * 10px) ;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
// *************功能一:生成目录******************************
var eles = ['h1', 'h2' , 'h3' ]
// 获取文章里 h1 到 h6 的元素 , 'h3', 'h4', 'h5', 'h6'
var doms = document.querySelector('.entry-content').querySelectorAll(eles.toString())
if (! doms || ! doms.length) {
return ;
}
// 创建目录盒子
let $ul = $('<ul class="catalogbox"></ul>')
// 目录的下标
let index = 0
for (let h of doms) {
let tag = h.nodeName.toLowerCase()
if (! eles.includes(tag)) {
continue ;
}
// 生成每个目录的id,绑定在 h 标签上
let id = `catalog_${++index}`
h.setAttribute('id', id)
// 获取 h 标签的内容
let text = h.innerHTML.replace(/<\/?[^>]+>/g, '')
// 生成 li 元素,需要绑定h 的id,以便于点击目录时可以找到对应的 h 标签
let level = tag.replace('h', '') // 获取当前目录级别,需要根据目录级别设置css
// let $li = `<li catalog="${id}">${text}</li>`
let $li = `<li style="--level: ${level}" catalog="${id}"">${text}</li>`
$ul.append($li)
}
$('#navDivId').append($ul)
// *************功能二:点击目录滚动到对应区域******************************
$('li[catalog]').on('click', function() {
// 获取每个li 上绑定的catalog值,对应着唯一的 h 标签
let id = $(this).attr('catalog')
document.querySelector(`#${id}`).scrollIntoView({
behavior: 'smooth'
})
})
// *************功能三:目录跟随滚动高亮******************************
window.addEventListener('scroll', function() {
// 获取浏览器滚动条距离顶部的高度
let scroll = document.documentElement.scrollTop || document.body.scrollTop
for (let i = doms.length - 1; i >= 0 ; i--) {
// 倒叙遍历所有的 h 标签,如果滚动条的 scrollTop 刚刚大于 h 区域的 offsetTop,
// 将此h 标签对应的 目录 设置为高亮
if (parseInt(scroll) >= Math.ceil(doms[i].offsetTop) ) {
let id = doms[i].getAttribute("id")
$('li[catalog]').each(function() {
if ($(this).attr('catalog') === id) {
$(this).addClass('current-catalog')
} else {
$(this).removeClass('current-catalog')
}
})
break ;
}
}
})
})
// 获取当前目录级别,需要根据目录级别设置css
let level = tag.replace('h', '')
// 生成 li 元素
let $li = `<li style="--level: ${level}" catalog="${id}"">${text}</li>`
</script>
<div class="sider-list-2">
<ul>
<h3>Share this article<h3/>
<i> </i> <i> </i> <i> </i> <i> </i>
</ul>
</div>