JS 根据文章中的标题生成目录索引
在浏览一些博客或 wiki 类网站的时候,你可能会发现在文章的开头或侧边会有一个目录,点击就可以跳转到指定的章节。对于比较长的文章来说,目录还是比较重要的。通过目录可以快速了解文章包含的内容,要查看某个章节也可以直接跳转。
最近准备给博客增加一个生成文章目录的功能,下面简单写一下实现方式。
代码
我这里使用了 jQuery,代码如下:
// 给 h2 到 h5 增加一个 content-title 的 class
$('.post-content h2').addClass('content-title');
$('.post-content h3').addClass('content-title');
$('.post-content h4').addClass('content-title');
$('.post-content h5').addClass('content-title');
// 给 h2 到 h5 增加一个 data-index 的自定义属性
$('.post-content h2').attr('data-index', 2);
$('.post-content h3').attr('data-index', 3);
$('.post-content h4').attr('data-index', 4);
$('.post-content h5').attr('data-index', 5);
// 函数的一个参数是标题级别,第二个参数是第一个标题的索引值
function atalog(titleIndex, start) {
// 存储 HTML 和当前的索引值
var el = {
el: '',
index: start
};
var current = 0; // 已遍历的数量
for (var i = start;i < $('.content-title').length;i ++) {
if (i < current) {
// 如果当前 i 的值小于已遍历的数量就跳过
continue;
}
if ($('.content-title').eq(i).attr('data-index') > titleIndex) {
// 如果是更小一级的标题就调用自身继续查找
var result = atalog($('.content-title').eq(i).attr('data-index'), i);
// 把返回的 HTML 添加到当前函数的 el 中
el.el += '<li> ' + result.el + '</li>';
current = result.index + 1; // 设置已遍历的数量
el.index = result.index; // 设置索引
continue; // 跳过本次循环
}
if ($('.content-title').eq(i).attr('data-index') < titleIndex) {
// 如果是更大一级的标题就返回已生成的 HTML 目录
el.el = '<ul class="mb-2">' + el.el + '</ul>';
return el;
}
// 生成 HTML 目录
el.el += '<li><a data-index="' + i + '" href="javascript:;">' + $('.content-title').eq(i).text() + '</a></li>';
el.index = i; // 设置当前的索引值为 i
}
// 添加列表的外层 ul
el.el = '<ul class="mb-2"> ' + el.el + '</ul>';
return el; // 返回生成的 HTML 目录
}
// 调用生成目录的函数,从第 0 个 h2 开始
var el = atalog(2, 0);
// 把生成的目录插入到文章的开头
$('.post-content').prepend('<div class="atalog">' + el.el + '</div>');
// 给生成的目录添加点击事件
$('.post-content .atalog a').on('click', function () {
// 设置滚动条的高度为标题的 offsetTop
$(document).scrollTop($('.content-title').eq($(this).attr('data-index')).offset().top);
});
上面的文章内容就在 class
为 post-content
的元素中。
简单说明
上面生成目录是从 h2
开始遍历,不包含 h1
。
先给 h2
、h3
、h4
、h5
添加相同的 class
,再给 h2
、h3
、h4
、h5
添加 2
、3
、4
、5
的 data-index
属性,用来区分标题等级。
函数的第一个参数是最大的标题等级,上面设置的是 2
,也就是代表 h2
。第二个参数是开始遍历的索引,上面设置为 0
就是从第 0
个标题开始遍历。
如果遍历到更小一级的标题就调用自身,传入更小一级的标题和当前的索引值继续遍历。如果遍历到更大一级的标题就返回生成的 HTML 目录。
遍历完成后生成 HTML 目录列表,然后返回 HTML 目录列表。
目录跳转可以通过改变滚动条的高度来跳转,也可以给标题和链接添加 id
跳转。如果通过 id
跳转的话,一些使用固定定位的导航栏可能会挡住标题,而通过改变滚动条高度来跳转就可以很方便的设置标题显示的位置。
效果
以 Sass 简单使用教程 这篇文章为例,生成的目录如下:
上面图片中的目录还没有添加 CSS。
通过 JS 生成文章目录的方式有很多,我这里的算是比较简单的一种,但不是最优的一种。
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/857/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。