cheerio制作markDown索引目录
制作目录索引这种东西当然是放在前端方便。选择放在后端一是为了了解Node后端生态,掌握更多后端技术;二是因为公司实行前后端分离的方式开发,睾贵的JAVA后端经常啥也不做处理就返回一个row数据(甚至有时时间戳都不处理),对此有些无语。
最终目标

- 点击索引单项跳转到相应标题
- 大号标题包含小号标题,小号标题向右缩进
- 滚动页面时自动切换索引项active状态
实现方法
md转化为html
const markDown = require('marked')
markDown.setOptions({
headerIds: false,
highlight: function(code) {
return require('highlight.js').highlightAuto(code).value;
},
})
let html = markDown(data.content)
cheerio生成索引
const cheerio = require('cheerio')
// decodeEntities防止中文转化为unicdoe
const $ = cheerio.load(html,{decodeEntities: false})
// 用hNum生成自定义id
let hArr = [], highestLvl, hNum = 0
$('h1, h2, h3, h4, h5, h6').each(function () {
let id = `h${hNum}`
hNum++
$(this).attr('id', id)
let lvl = $(this).get(0).tagName.substr(1)
if(!highestLvl) highestLvl = lvl
hArr.push({
lvl: lvl - highestLvl + 1,
content: $(this).html(),
id: id
})
})
Object.assign(data, {
content: $.html,
toc: hArr
})
前台展示
if data && data.toc
ul#toc-wrapper.toc-wrapper-transform
each item in data.toc
// 利用lvl判断偏移量
li(class='toc-item text-elli', style=`padding-left: ${item.lvl * 15}px`, id=item.id)
a(href=`#${item.id}`, title=item.content).text-elli= item.content
页面滚动过自动切换active
知道getBoundingClientRect API就好做了
function tocToggle() {
if($('.article-content').dom.length == 0) return
let scrollArr = []
document.querySelectorAll('.article-content h1, h2, h3, h4, h5, h6').forEach(i => {
let elTop = Math.abs(i.getBoundingClientRect().top)
scrollArr.push({
el: i,
top: elTop
})
})
if(scrollArr.length == 0) return
scrollArr = scrollArr.sort((a, b) => {
return a.top - b.top
})
let activeId = $(scrollArr[0].el).attr('id')
$(`#toc-wrapper #${activeId}`).ac('toc-item-active').siblings().rc('toc-item-active')
}
$(window).on('scroll', () => {
tocToggle()
})
tocToggle()
Tips
锚点偏移
本网站的header是fixed在顶部的,锚点不进行偏移会盖住标题。偏移方法:
h1, h2, h3, h4, h5, h6{
&:target{
padding-top: 60px
}
}
cheerio制作markDown索引目录的更多相关文章
- IntelliJ IDEA 转移C盘.IntelliJIdea(索引目录)
转移原因: C盘是机械硬盘,并且容量不多的情况下,建议转移. 转移步骤: 找到索引目录 win10系统下默认路径:C:\Users\asus\.IntelliJIdea2016.2 *复制或剪切到新的 ...
- lucene全文搜索之二:创建索引器(创建IKAnalyzer分词器和索引目录管理)基于lucene5.5.3
前言: lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器.管理索引目录和中文分词器的使用. 包括标准分词器,IKAnalyzer分词器以及两种索引目录的创 ...
- 【一天一道LeetCode】索引目录 ---C++实现
[一天一道LeetCode]汇总目录 这篇博客主要收藏了博主所做题目的索引目录,帮助各位读者更加快捷的跳转到对应题目 目录按照难易程度:easy,medium,hard来划分,读者可以按照难易程度进行 ...
- 使用word设置标题级别, 自动生成和大纲对应的多级列表, 自动生成索引目录
作为程序员,只会开发是不够的, 在日常工作中还需要掌握一些办公软件的的操作方法,word excel ppt精通不敢, 暂且入个门吧, 在前后台开发配合过程中,能写的一手好文档将会达到事半功倍的效果, ...
- IntelliJ IDEA 转移 C盘.IntelliJIdea 索引目录
IntelliJ IDEA 索引目录默认路径是 C:\Users\用户\.IntelliJIdea 转移步骤 1. 将 C:\Users\用户\.IntelliJIdea 索引目录剪切到要移动到的 ...
- lucene 多索引目录搜索实现方法
http://akululu.iteye.com/blog/314130 多索引目录就是要在多个索引目录的中进行比较搜索,类似概念在SQL中就是select * from TableA union s ...
- nginx索引目录配置
为了简单共享文件,有些人使用svn,有些人使用ftp,但是更多得人使用索引(index)功能.apache得索引功能强大,并且也是最常见得,nginx得auto_index实现得目录索引偏少,而且功能 ...
- Nginx中的root&alias文件路径及索引目录配置详解
这篇文章主要介绍了Nginx中的root&alias文件路径及索引目录配置,顺带讲解了root和alias命令的用法,需要的朋友可以参考下 root&alias文件路径配置ng ...
- 《Windows内核安全与驱动开发》阅读笔记 -- 索引目录
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 一.内核上机指导 二.内核编程环境及其特殊性 2.1 内核编程的环境 2.2 数据类型 2.3 重要的数据结构 2.4 函数调 ...
随机推荐
- Apache Continuum 远程命令执行漏洞
这个是apache现在不维护的服务了. 服务使用了struts2框架,目前测试是使用的最新版.
- SetConsoleCtrlHandler演示
#include "stdafx.h"#include <Windows.h> static BOOL WINAPI Handler(DWORD cntrlEvent) ...
- 第一章 深入Web请求过程(待续)
B/S网络架构概述 如何发起一个请求 HTTP解析 DNS域名解析 CDN工作机制
- 第五章 JVM调优(待续)
Java虚拟机内存模型 JVM内存分配参数 垃圾收集基础 常用调优案列和方法 实用JVM参数 实战JVM调优
- python使用pyodbc连接sql server 2008
一.PyODBC的下载地址: http://code.google.com/p/pyodbc/ 二.测试语句 import pyodbccnxn = pyodbc.connect(DRIVER='{S ...
- NSURLConnection基本用法(苹果原生)
一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest/NSMutableURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSUR ...
- Shell编程进阶 1.8 for循环
产生序列的命令 seq 1 2 3 4 5 6 7 8 9 10 seq 1 3 5 7 9 (从1开始增加2显示这个数字,到10结束) seq - 10 8 6 4 2 seq - 10 9 8 ...
- 第6章 使用springboot整合netty搭建后台
我们不会去使用自增长的id,在现阶段的互联网开发过程中,自增长的id是已经不适用了.在未来随着系统版本的迭代,用户数量的递增,肯定会做分库分表,去做一些相应的切分.在这个时候我们就需要有一个唯一的id ...
- CSS中cursor的pointer 与 hand(转)
CSS中cursor的pointer 与 hand 转载 2015年12月25日 16:18:36 标签: cursorpointer / cursorhand 1781 cursor:hand 与 ...
- 洛谷P2146 树链剖分
题意 思路:直接树链剖分,用线段树维护即可,算是树剖的经典题目吧. 代码: #include <bits/stdc++.h> #define ls(x) (x << 1) #d ...