纯js实现文章导航目录

3,792 阅读1分钟

我们经常看到一些内容较多的文章都有一个目录导航,点击导航会跳转到响应的位置,页面滚动时相应位置的导航也会呈现选中状态非常的方便,这里使用js做一个简单的实现

实现思路

  • 为文章中的标题标签h1、h2添加不同的id(举例只取h1、h2其他同理)
  • 正则获取文章内容中的h1、h2标签
  • 使用将获取到的标签转换成li、a标签,id转换为href属性
  • 将转换后的标签插入需要显示目录的位置
  • 编写监测页面滚动监听事件
  • 编写描点点击事件

为文章中的标题标签添加不同的id

需要保证页面中的id不重复,这里使用了循环赋值的方法

//遍历h1 h2重设id
let idList = 1;
$('.j-article-conn h1').each(function () {
	$(this).attr('id', idList);
	idList++;
});
$('.j-article-conn h2').each(function () {
	$(this).attr('id', idList);
	idList++;
});

正则获取文章内容中的标题标签

使用正则一行代码即可实现:

let a = $('.j-article-conn').html().match(/<h1.*?<\/h1>|<h2.*?<\/h2>/g);

根据实际情况的不同正则需要做相应的修改

使用将获取到的标签转换成li、a标签,id转换为href属性

for (let i = 0; i < a.length; i++) {
	a[i] = a[i].replace(/id="/g, 'href="#')
	if (a[i].indexOf('h2') != -1) {
		a[i] = '<li class="pl">' + a[i].replace(/h2/g, 'a') + '</li>'
	} else {
		a[i] = '<li>' + a[i].replace(/h1/g, 'a') + '</li>'
	}
}

这里的判断为h2标签添加了不同的样式便于区分

将转换后的标签插入需要显示目录的位置

$('.j-titleList').prepend(a)

编写监测页面滚动监听事件

//获取id数组
for (let i = 0; i < a.length; i++) {
    a[i] = a[i].replace(/.*?#(.*)".*/g, '$1')
}
//页面滚动为导航添加样式
$(window).scroll(function () {
	for (let i = 0; i < a.length; i++) {
		if ($(window).scrollTop() > $('#' + a[i]).offset().top - 100 || $(this).scrollTop() + $(this).height() == $(document).height()) {
			$('.j-titleList').find('li').eq(i).addClass('active').siblings('li').removeClass('active');
			$('.j-bj').css('top', i * 44)
		}
	}
});

编写描点点击事件

为点击的目录添加选中样式,添加平滑滚动动画,css样式需要自己定义

let $root = $('html, body');
$('.j-titleList li a').on("click", function () {
	$root.animate({
		scrollTop: $($.attr(this, 'href')).offset().top - 65
	}, 400);
	return false
});

效果预览: blog.qianxiaoduan.com/archives/20…

永久链接: blog.qianxiaoduan.com/archives/20…