搜索
您的当前位置:首页正文

js实现文章目录索引导航(tableofcontent)

来源:欧得旅游网
js实现⽂章⽬录索引导航(tableofcontent)

什么叫TOC呢?table of content。

具体什么效果呢?可以随便找个hexo博客中体验⼀下,例如这个。好了,实现它有2个要点:

点⽬录跳到段落:通过标签的锚点实现,其原理在。

滚动触发⽬录变换:通过js监听滚动事件,判定当前所处段落,令对应⽬录项⾼亮。我写了⼀个简单的demo来演⽰这个效果,实现分析

#toc是左侧的⽬录,#content是右侧的⽂章正⽂。

利⽤css控制#toc靠左,当前⽬录⾼亮为红⾊,正⽂则靠右填满屏幕:

#toc {

width: 200px; position: fixed; left: 0; top: 0; }

#toc a.active { color: red; }

#content {

margin-left: 200px; }

在上⾯的静态页⾯中,⽬录暂时为空,因为需要⽤JS动态⽣成。

正⽂中需要⼈⼯埋点段落起始标识,也就是a.seg-begin这样的锚点,每个段落的锚点name唯⼀,⽽锚点之后紧随段落的内容。

在JS中,我⾸先按锚点的出现次序收集所有的a.seg-begin保存到segs数组中,其顺序就是⽂章⾃上⽽下的阅读顺序,按照其

中的段落标题建出#toc中的
    列表:

    var segs = [];

    $(\".seg-begin\").each(function (idx, node) { segs.push(node)

    var link = $(\"\").attr(\"href\ if (!idx) {

    link.addClass(\"active\") }

    var row = $(\"

  • \").append(link) $(\"#toc ul\").append(row) })

    然后绑定浏览器的scroll事件进⾏监听,每次滚动就判断最近⼀个滚出屏幕顶部的a.seg-begin节点,它就是当前正在阅读的段落:

    $(window).bind(\"scroll\ var scrollTop = $(this).scrollTop() var topSeg = null

    for (var idx in segs) { var seg = segs[idx]

    if (seg.offsetTop > scrollTop) { continue }

    if (!topSeg) { topSeg = seg

    } else if (seg.offsetTop >= topSeg.offsetTop) { topSeg = seg } }

    if (topSeg) {

    $(\"#toc a\").removeClass(\"active\")

    var link = \"#\" + $(topSeg).attr(\"name\")

    console.log('#toc a[href=\"' + link + '\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" ]')

    $('#toc a[href=\"' + link + '\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" ]').addClass(\"active\") // console.log($(topSeg).children(\"h1\").text()) } })

    后续

    这⾥⽬录的⽣成是在前端JS⾥根据正⽂的锚点动态⽣成的,为了SEO可以在后端提交⽂章正⽂时匹配出这些锚点,直接保存为⽬录。完整代码

    另外,这⾥没有实现嵌套的⽬录结构,我特意观察了⼀下hexo的做法,是通过h1,h2,h3来表达层级的,这样在each遍历⽣成⽬录的时候可以基于这个信息完成嵌套层级的标记,问题迎刃⽽解。

    因篇幅问题不能全部显示,请点此查看更多更全内容

Top