原文地址:小寒的博客

功能介绍

这个组件的效果呐,就是你在浏览这个页面的时候点击右上角的叉叉看到的那个文章目录。

功能很简单,就是根据文章内容自动生成这个目录,可以快速跳转。

需要的知识点

  • 正则
  • dom操作
  • 利用锚点跳转

实现原理

  1. 首先我们拿到的是一个html字符串,并不是html哦,然后分析这个html字符串,获取所有的h1 h2 h3 h4 h5 h6的生成一个锚点信息的列表
  2. 然后给所有的这些标题标记一个id,用来进行锚点的跳转
  3. 渲染目录

正则

正则是基础中最难学和应用的一部分,但作为处理字符串最高效的一个方式,也是开发者进阶必不可少的知识点。

获取所有 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实现一个自动生成文章目录的组件的更多相关文章

  1. CSDN中根据文章自动生成文章目录

    概述 CSDN中有根据文件内容中H标签在文章中自动生成文章目录,看起来比较专业,就想把它搬到自己的博客园中.类似下图 提取JS脚本 通过浏览器开发者工具(IE/Chrome)找到产生文章目录javas ...

  2. React 创建一个自动跟新时间的组件

    componentDidMount声明周期函数 表示组件渲染完成后 componentWillUnmount声明周期函数 组件将要卸载 通常用于(为了防止内存泄漏 清除定时器) 11==>创建组 ...

  3. 用jquery实现文章自动生成二级目录(续)

    前文:用jquery实现文章自动生成二级目录. 使用方法的补充 我们可以把我们的js和css上传到博客园,然后在页面HTML代码中使用他们. 发现的一些问题 在我把我的js放到自己的博客园上运行之后发 ...

  4. 用jquery实现文章自动生成二级目录

    前段时间有个同学问有没有办法在博客园上发一篇文章然后自动生成文章的目录.之前不知道该怎么做这几天看了些jquery之后觉得还是容易的. 一级目录 一级目录的思路很简单,找出作为一级标题的元素,在某个地 ...

  5. TP自动生成模块目录

    TP自动生成模块目录 例如我想在项目中增加一个AdminI模块 只需要在入口文件index.php中添加: define('BIND_MODULE','Admin'); 再访问127.0.0.1项目就 ...

  6. HelloDjango 第 11 篇:自动生成文章摘要

    作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 博客文章的模型有一个 excerpt 字段,这个字段用于存储文章的摘要.目前为止,还只 ...

  7. JavaScript自动生成博文目录导航

    转载于:JavaScript自动生成博文目录导航 我们在写博客的时候,如果博文里面有目录,会给人结构清晰.一种一目了然的感觉,看目录就知道这篇博文要讲解的内容,并且点击目录标题就可以跳转到 具体的内容 ...

  8. 使用autoc js生成文章目录(侧边)导航栏

    介绍: autocjs 是一个专门用来生成文章目录(Table of Contents)导航的工具.autocjs 会查找文章指定区域中的所有 h1~h6 的标签,并自动分析文章的层次结构,生成文章的 ...

  9. JavaScript自动生成博文目录导航/TOP按钮

    博客园页面添加返回顶部TOP按钮 进入网页管理->设置 在"页面定制CSS代码"中添加如下css样式,当然你可以改为自己喜欢的样式 此处可以将背景色background-co ...

随机推荐

  1. nutch2.2.1+mysql抓取数据

    基本环境:linux centos6.5 nutch2.2.1 源码包, mysql 5.5 ,elasticsearch1.1.1, jdk1.7 1.下载地址http://mirror.bjtu. ...

  2. HTML_案例(首页制作)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. CSIC_716_20191115【内置函数、递归、模块、软件开发规范】

    内置函数 map map映射:语法结构(函数对象,可迭代对象) 依次从可迭代对象中取值,然后给函数做运算,再依次返回运算的结果. ss = map(lambda x: x + x, [1, 2, 3] ...

  4. [转]SSM(Spring+SpringMVC+Mybatis)框架搭建详细教程【附源代码Demo】

    一.新建项目 运行IDEA,进入初始化界面,然后我们选择新建项目(进入主界面新建项目也是一样的) 在Maven选项卡里面找到对应的java web选项,然后我们点下一步 这一步填入组织等信息,这里比较 ...

  5. [JZOJ4665] 【GDOI2017模拟7.21】数列

    题目 题目大意 给你一个数列,让你找到一个最长的连续子序列,满足在添加了至多KKK个数之后,能够变成一条公差为DDD的等差数列. 思考历程 一眼看上去似乎是一道神题-- 没有怎么花时间思考,毕竟时间都 ...

  6. Scala 方法与函数简单记录

    /** * Scala 方法与函数 * Scala 有方法与函数,二者在语义上的区别很小.Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量.换句话来说在类中定义的函数即是方法 */ o ...

  7. npm与cnpm两者之间的区别是什么?

    NPM(节点包管理器)是节点的包管理器,用于管理节点插件(包括安装.卸载和管理依赖关系等).).NPM是一个软件包管理工具,安装在新版本的节点上,所以我们需要安装节点. NPM的常用场景(http:/ ...

  8. csps退役记

    AFO 省二稳了,指望文化课吧 hzoi加油

  9. kubernetes istio之流量管理

    1.部署 Bookinfo 应用 要在 Istio 中运行这一应用,无需对应用自身做出任何改变.我们只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar ...

  10. 基于V8引擎的C++和JS的相互交互

    基于什么原因略! 1. 脚本引擎的基本功能 V8只是一个JS引擎.去除它的特点功能出处,它必须要实现JS引擎的几个基础功能: 脚本执行:脚本可能是一个表达式:一段js代码:或者一个文件执行表达式返回j ...