给文章增加侧边导航栏

看到这个需求,第一感觉肯定是装插件,因为Markdown文章其实是自带目录的,只要在文章中加一句@TOC,目录就会自己生成,但是如果文章本来就有目录,再获取一遍放旁边,显然要实现的并非这个效果,我们要做的是把文章中的标题获取出来,然后拼接成一个目录,最终效果如下图所示:
image.png

1、首先,先给文章加上一个id,方便后边获取到他。

<div class="nimbus-editor-styl" id="contents"  v-html="detail.content"></div>

2、给需要添加目录的地方放一个盒子

<div v-if="tocShow" id="toc"></div>

3、最重要的当然是获取标题,拼接目录

      var toc = "";
      var level = 0;
      if(document.querySelector('#contents')){
        var container = document.querySelector('#contents');
        var output = '#toc';
        let atitle = document.querySelectorAll('a')
        if(atitle){
          for(var i = 0;i < atitle.length;i++){
            atitle[i].style = 'padding-top: 64px;margin-top: -64px;'
          }
        }
        container.innerHTML.replace(/<h([\d])>(.*?)<\/h([\d])>/g,   //这一步是匹配到文章内容中的h1-h6标签
        function (str, openLevel, titleText, closeLevel) {
            if (openLevel != closeLevel) {
                return str;
            }
            if (openLevel > level) {                                //下一个比前一个小就一层,大就和上一场同级
              toc += (new Array(openLevel - level + 1)).join('<ul>');  
            } else if (openLevel < level) {
              toc += (new Array(level - openLevel + 1)).join('</li></ul>');
            } else {
              toc += (new Array(level+ 1)).join('</li>');
            }
            level = parseInt(openLevel);
            if(titleText.match(/<a(.*?)<\/a>/g)){            //匹配标题中的a标签
              let str1 = titleText.match(/<a(.*?)<\/a>/g)[0]
              let aid = str1.match(/id="(.*?)"/g)[0]        //匹配a标签中的id,并将id获取出来
              aid = aid.replace('id="', "").replace('"',"")
              titleText = titleText.replace(/<a(.*?)<\/a>/g, "")
              titleText = `<a href="#${aid}" class="font12 nowrap titleText">${titleText}</a></div>`
              toc += '<li><div class="flex mb4"><i class="nb-pull-down"></i>' + titleText;
            }
        });
        if (level) {
          toc += (new Array(level + 1)).join('</ul>');
        }
        if(toc.match(/<ul><ul>/g)){                //因为匹配时发现结果中出现多个空的ul标签,这里替换掉空的
           toc = toc.replace(/<ul><ul><ul>+/g,'<ul>').replace(/<\/ul><\/ul> <\/ul>+/g,'</ul>')
        }                
        document.querySelector(output).innerHTML = ''
        document.querySelector(output).innerHTML += toc;
        let liArr = document.querySelectorAll('li')    //因为拼接好的目录只有margin来决定层级,所有决定给他增加一个icon,此时需要判断,如果li没有下一层,就不加icon,如果有下一层,则加上icon
        if(liArr){
          for(var i = 0;i < liArr.length;i++){ 
            if(liArr[i].innerHTML.match('<ul>')){
            }else{
              liArr[i].innerHTML = liArr[i].innerHTML.replace('<i class="nb-pull-down"></i>','').replace('font12 nowrap titleText','font12 nowrap titleText ml16')
            }
          }
        }
      }else{
        return
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值