原文地址:cheerio制作markDown索引目录

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

最终目标

  1. 点击索引单项跳转到相应标题
  2. 大号标题包含小号标题,小号标题向右缩进
  3. 滚动页面时自动切换索引项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索引目录的更多相关文章

  1. IntelliJ IDEA 转移C盘.IntelliJIdea(索引目录)

    转移原因: C盘是机械硬盘,并且容量不多的情况下,建议转移. 转移步骤: 找到索引目录 win10系统下默认路径:C:\Users\asus\.IntelliJIdea2016.2 *复制或剪切到新的 ...

  2. lucene全文搜索之二:创建索引器(创建IKAnalyzer分词器和索引目录管理)基于lucene5.5.3

    前言: lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器.管理索引目录和中文分词器的使用. 包括标准分词器,IKAnalyzer分词器以及两种索引目录的创 ...

  3. 【一天一道LeetCode】索引目录 ---C++实现

    [一天一道LeetCode]汇总目录 这篇博客主要收藏了博主所做题目的索引目录,帮助各位读者更加快捷的跳转到对应题目 目录按照难易程度:easy,medium,hard来划分,读者可以按照难易程度进行 ...

  4. 使用word设置标题级别, 自动生成和大纲对应的多级列表, 自动生成索引目录

    作为程序员,只会开发是不够的, 在日常工作中还需要掌握一些办公软件的的操作方法,word excel ppt精通不敢, 暂且入个门吧, 在前后台开发配合过程中,能写的一手好文档将会达到事半功倍的效果, ...

  5. IntelliJ IDEA 转移 C盘.IntelliJIdea 索引目录

    IntelliJ IDEA 索引目录默认路径是  C:\Users\用户\.IntelliJIdea 转移步骤 1. 将  C:\Users\用户\.IntelliJIdea 索引目录剪切到要移动到的 ...

  6. lucene 多索引目录搜索实现方法

    http://akululu.iteye.com/blog/314130 多索引目录就是要在多个索引目录的中进行比较搜索,类似概念在SQL中就是select * from TableA union s ...

  7. nginx索引目录配置

    为了简单共享文件,有些人使用svn,有些人使用ftp,但是更多得人使用索引(index)功能.apache得索引功能强大,并且也是最常见得,nginx得auto_index实现得目录索引偏少,而且功能 ...

  8. Nginx中的root&alias文件路径及索引目录配置详解

    这篇文章主要介绍了Nginx中的root&alias文件路径及索引目录配置,顺带讲解了root和alias命令的用法,需要的朋友可以参考下     root&alias文件路径配置ng ...

  9. 《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 一.内核上机指导 二.内核编程环境及其特殊性 2.1 内核编程的环境 2.2 数据类型 2.3 重要的数据结构 2.4 函数调 ...

随机推荐

  1. Apache Continuum 远程命令执行漏洞

    这个是apache现在不维护的服务了. 服务使用了struts2框架,目前测试是使用的最新版.

  2. SetConsoleCtrlHandler演示

    #include "stdafx.h"#include <Windows.h> static BOOL WINAPI Handler(DWORD cntrlEvent) ...

  3. 第一章 深入Web请求过程(待续)

    B/S网络架构概述 如何发起一个请求 HTTP解析 DNS域名解析 CDN工作机制

  4. 第五章 JVM调优(待续)

    Java虚拟机内存模型 JVM内存分配参数 垃圾收集基础 常用调优案列和方法 实用JVM参数 实战JVM调优

  5. python使用pyodbc连接sql server 2008

    一.PyODBC的下载地址: http://code.google.com/p/pyodbc/ 二.测试语句 import pyodbccnxn = pyodbc.connect(DRIVER='{S ...

  6. NSURLConnection基本用法(苹果原生)

    一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest/NSMutableURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSUR ...

  7. 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 ...

  8. 第6章 使用springboot整合netty搭建后台

    我们不会去使用自增长的id,在现阶段的互联网开发过程中,自增长的id是已经不适用了.在未来随着系统版本的迭代,用户数量的递增,肯定会做分库分表,去做一些相应的切分.在这个时候我们就需要有一个唯一的id ...

  9. CSS中cursor的pointer 与 hand(转)

    CSS中cursor的pointer 与 hand 转载 2015年12月25日 16:18:36 标签: cursorpointer / cursorhand 1781 cursor:hand 与 ...

  10. 洛谷P2146 树链剖分

    题意 思路:直接树链剖分,用线段树维护即可,算是树剖的经典题目吧. 代码: #include <bits/stdc++.h> #define ls(x) (x << 1) #d ...