用React实现一个自动生成文章目录的组件
原文地址:小寒的博客
功能介绍
这个组件的效果呐,就是你在浏览这个页面的时候点击右上角的叉叉看到的那个文章目录。

功能很简单,就是根据文章内容自动生成这个目录,可以快速跳转。
需要的知识点
- 正则
- dom操作
- 利用锚点跳转
实现原理
- 首先我们拿到的是一个html字符串,并不是html哦,然后分析这个html字符串,获取所有的h1 h2 h3 h4 h5 h6的生成一个锚点信息的列表
- 然后给所有的这些标题标记一个id,用来进行锚点的跳转
- 渲染目录
正则
正则是基础中最难学和应用的一部分,但作为处理字符串最高效的一个方式,也是开发者进阶必不可少的知识点。
获取所有 h1-h6 标签的正则
/<(h\d).*?>.*?<\/h\d>/
<(h\d).*?>是第一个标签 \d表示数字 ,注意这个有个括号,用来分组匹配,这个分组可以获得这个标签
.*表示一个标签的内容,不管是什么
?表示非贪婪的,抓够就撤退
<\/h\d>是结尾的标签
String.prototype.replace
content.replace(/<(h\d)>.*?<\/h\d>/g, (match, tag) => {
const hash = match.replace(/<.*?>/g, '')
tables.push({ hash, tag })
return `<a class="blog-content-anchor" href="#${hash}" id="${hash}">${match}</a>`
})
replace方法接受的第一个参数就是这个正则,第二个是一个匹配的函数,参数的第一个是匹配的结果,第二个就是分组匹配的结果
hash就是标题的内容,比如
<h1>我是标题</h1>
就会被转化成
<a class="blog-content-anchor" href="#我是标题" id="我是标题"><h1>我是标题</h1></a>
所以我们可以用tables记录这个目录的信息,包括作为hash的标题内容和他的标签,即他是h1还是h2还是h3,现在就可以实现点击标题,自动定位到这个标题了
而此时生成的tables应该是这个样子

渲染
{tables.length > &&
<Drawer>
<div className="blog-table" ref={this.table}>
<h4>目录</h4>
{tables.map(({ hash, tag }, index) => (
<div key={index} className="blog-table-item">
<a
className={"blog-table-item-" + tag}
href={'#' + hash}
onClick={e => this.handleScroll(e, hash)}
>{hash}</a>
</div>
))}
</div>
</Drawer>
}
既然拿到目录的信息,就可以生成目录了
大功告成,最后呐,贴上我的源代码,供大家参考
https://github.com/soWhiteSoColl/blog-web/blob/master/components/widgets/Blog.jsx
用React实现一个自动生成文章目录的组件的更多相关文章
- CSDN中根据文章自动生成文章目录
概述 CSDN中有根据文件内容中H标签在文章中自动生成文章目录,看起来比较专业,就想把它搬到自己的博客园中.类似下图 提取JS脚本 通过浏览器开发者工具(IE/Chrome)找到产生文章目录javas ...
- React 创建一个自动跟新时间的组件
componentDidMount声明周期函数 表示组件渲染完成后 componentWillUnmount声明周期函数 组件将要卸载 通常用于(为了防止内存泄漏 清除定时器) 11==>创建组 ...
- 用jquery实现文章自动生成二级目录(续)
前文:用jquery实现文章自动生成二级目录. 使用方法的补充 我们可以把我们的js和css上传到博客园,然后在页面HTML代码中使用他们. 发现的一些问题 在我把我的js放到自己的博客园上运行之后发 ...
- 用jquery实现文章自动生成二级目录
前段时间有个同学问有没有办法在博客园上发一篇文章然后自动生成文章的目录.之前不知道该怎么做这几天看了些jquery之后觉得还是容易的. 一级目录 一级目录的思路很简单,找出作为一级标题的元素,在某个地 ...
- TP自动生成模块目录
TP自动生成模块目录 例如我想在项目中增加一个AdminI模块 只需要在入口文件index.php中添加: define('BIND_MODULE','Admin'); 再访问127.0.0.1项目就 ...
- HelloDjango 第 11 篇:自动生成文章摘要
作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 博客文章的模型有一个 excerpt 字段,这个字段用于存储文章的摘要.目前为止,还只 ...
- JavaScript自动生成博文目录导航
转载于:JavaScript自动生成博文目录导航 我们在写博客的时候,如果博文里面有目录,会给人结构清晰.一种一目了然的感觉,看目录就知道这篇博文要讲解的内容,并且点击目录标题就可以跳转到 具体的内容 ...
- 使用autoc js生成文章目录(侧边)导航栏
介绍: autocjs 是一个专门用来生成文章目录(Table of Contents)导航的工具.autocjs 会查找文章指定区域中的所有 h1~h6 的标签,并自动分析文章的层次结构,生成文章的 ...
- JavaScript自动生成博文目录导航/TOP按钮
博客园页面添加返回顶部TOP按钮 进入网页管理->设置 在"页面定制CSS代码"中添加如下css样式,当然你可以改为自己喜欢的样式 此处可以将背景色background-co ...
随机推荐
- mybatis 处理CLOB/BLOB类型数据
BLOB和CLOB都是大字段类型. BLOB是按二进制来存储的,而CLOB是可以直接存储文字的. 通常像图片.文件.音乐等信息就用BLOB字段来存储,先将文件转为二进制再存储进去.文章或者是较长的文字 ...
- lambda x:i*x for i in range(4)
解决方法:冒号前添加接收 i 的变量 return [lambda x,i=i: i * x for i in range(4)]
- json、pickle和base64
json.dumps() 用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. json.dump() 用于将dict类 ...
- MySQL 不用 Null 的理由
Null 貌似在哪里都是个头疼的问题,比如 Java 里让人头疼的 NullPointerException,为了避免猝不及防的空指针异常,千百年来程序猿们不得不在代码里小心翼翼的各种 if 判断,麻 ...
- 【笔记篇】斜率优化dp(四) ZJOI2007仓库建设
传送门戳这里>>> \(n\leq1e6\), 显然还是\(O(n)\)的做法. 这个题有个条件是只能运往编号更大的工厂的仓库, 这也是写出朴素dp的方程的条件. 我们令\(f[i] ...
- AM8不能下任何载附件及所有聊天记录无法登记
问题描述: 接收附件时,点击打开或者下载都不成功,但可以发送消息和附件.但在消息管理器中,也查询不到发送和接收的消息 原因分析:此问题是windows开机登录用户权限问题(若 登录的账号是 whx), ...
- JavaScript - 常用对象相关
1. String对象 length : 字符串的长度 charAt(index) : 返回指定位置的字符串, 下标从0开始 indexOf(str) : 返回指定的字符串在当前字符串中首次出现的位置 ...
- mac 10.9 install cocoapods issue
If you've installed the OS X Mavericks Beta and you're having ruby issues like this: /System/Library ...
- 在idesktop中加载天地图服务并叠加矢量数据
在天地图中加载天地图在线服务,然后叠加上我们制作的专题图,可以查看制图效果. 以加载山东省天地图矢量地图服务为例: 服务地址: http://www.sdmap.gov.cn/tileservice/ ...
- android studio 正式版本
注意:以下 Android Studio 下载链接全是 dl.google.com 开头的官方下载,无需tizi,建议用浏览器直接从官方原始链接下载,不要用迅雷下载.不要用迅雷下载.不要用迅雷下载,重 ...