bytemd 渲染 markdown 后实现仿掘金目录功能

463 阅读1分钟

效果如下

www.zqskate.com/post/175649…

image.png

原理

扫描 .markdown 下的 h1~h4 标题,组装成 antd 的 Anchor

代码

需要用到 antdAnchor 组件

import { Anchor } from 'antd';

const App = () => {
    const [anchors, setAnchors] = useState([]);
    
    const updateToc = () => {
      setTimeout(() => {
        const article = document.querySelector(".markdown-body");
        if (null === article || article.hasAttribute('querySelectorAll')) return;
        const hs = article.querySelectorAll('h1,h2,h3,h4');
        const anchor = [];
        hs.forEach((item, idx) => {
          const h = item.nodeName.substring(0, 2).toLowerCase();
          item.id = `Anchor-${h}-${idx}`;
          anchor.push({id: `Anchor-${h}-${idx}`, text: item.textContent});
        })
        setAnchors(anchor)
      }, 100);
    }
    
    return (
        <>
            <Anchor
              offsetTop={1}
              affix={false}
              showInkInFixed={true}
            >
              {anchors.map((anchor, idx) => {
                switch (anchor.id[8]) {
                  case "1": return  <Anchor.Link key={idx} href={`#${anchor.id}`} title={<span style={{paddingLeft: 0}}>{anchor.text}</span>}/>
                  case "2": return  <Anchor.Link key={idx} href={`#${anchor.id}`} title={<span style={{paddingLeft: 16}}>{anchor.text}</span>}/>
                  case "3": return  <Anchor.Link key={idx} href={`#${anchor.id}`} title={<span style={{paddingLeft: 32}}>{anchor.text}</span>}/>
                  default: return <></>
                }
              })}
            </Anchor>
        </>
    );
    
}