React中如何实现类似于segmentfault中文章右侧目录?

请教一下各位大佬

React中如何实现类似于segmentfault中文章右侧目录?

  • DOM元素来自于markdown转化的HTML
  • 文章页面分为文章内容组件和文章目录组件

具体来说就是怎么获取已经渲染在页面上的h2,h3,h4等DOM元素,然后展现它们的层级关系?

我之前有一个想法:用正则表达式去匹配HTML字符串,可以获得h2等元素,但是这样无法把握它们的层级关系。

在React中,又无法直接获取DOM元素。

所以想请教一下各位大佬~

给我一点提示就好~

阅读 6.4k
3 个回答

既然你是 Markdown,你可以先正则匹配下Markdown呀。

比如这样:

var markdown = `
# header1

## header2

### header3
`

var toc = [];
var reg = /(#+)\s+?(.+?)\n/g;
var regExecRes = null
while((regExecRes = reg.exec(markdown))) {
  toc.push({
    level: regExecRes[1].length,
    title: regExecRes[2]
  });
}
console.info(toc)

输出结果:

[
    {
        level: 1, 
        title: "header1"
    }
    {
        level: 2, 
        title: "header2"
    },
    {
        level: 3, 
        title: "header3"
    }
]

这样就好处理了,当然你可以做得更细致一些。

和我之前做博客展示有点像 文章例子
我是在渲染 markdown 阶段记录下了h3,h4这种标题,用的是marked

    let headInfo = []
    renderer.heading = function(text, level) {
        if(level == 3) {
            headInfo.push({
                id: `#hazyzh-h3-${++index1}`,
                text: text,
                children: []
            })
        } else if (level == 4) {
            let last = headInfo[headInfo.length - 1]
            last && last.children.push({
                id: `#hazyzh-h4-${++index2}`,
                text: text
            })
        } 
    }

你用正则匹配出来为啥无法把握层级关系,匹配到的顺序不就是层级关系么

这种目录大多数是在后端已经做好生成,因为后端只需要生成一次。而前端拿到的直接就是一个目录数据。

至于目录的生成方法有很多种,直接匹配HTML,匹配markdown。

当然如果你的markdown解析器支持自编写插件的话就更方便了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题