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 = $('h1, h2, h3, h4, h5, h6').each(function () { let id = `h${hNum}` hNum++ $(this).attr('id', id) let lvl = $(this).get().tagName.substr() if(!highestLvl) highestLvl = lvl hArr.push({ lvl: lvl - highestLvl + , 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 == ) 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 == ) return scrollArr = scrollArr.sort((a, b) => { return a.top - b.top }) let activeId = $(scrollArr[].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 } }
相关推荐
MarkDownHere 2020-09-16
xiongweiwei00 2020-06-28
Kingcxx 2020-06-25
Hesland 2020-06-14
tenvainvi 2020-06-11
amazingbo 2020-06-10
tenvainvi 2020-06-09
Kingcxx 2020-06-04
James0 2020-06-01
tenvainvi 2020-05-29
xiongweiwei00 2020-05-28
Hesland 2020-05-28
xiongweiwei00 2020-05-26
Hesland 2020-05-19
chzh0 2020-05-19