山大软院创新项目实训(五)

一、成果概述

基于博客(三),由于长博客看起来比较乱,所以加上了导航功能,导航栏可以帮助作者理清文章顺序,同时也能帮读者快速定位关键词。

二、实现思路

发布文章:

配置 toc 生成导航时包含的标题,标题范围是h1-h6:

VMdEditor.use(githubTheme, {
  config: {
    toc: {
      includeLevel: [1,2,3,4,5,6],
    },
  },
});

配置生成目录导航时包含的标题:

<v-md-editor :include-level="[1,2,3,4,5,6]"></v-md-editor>

效果展示:

1574089ca2c14e13aac4081fbed667bf.png

 

阅读文章:

        <el-card>
          <h1>·目录导航</h1><br>
          <!--    自定义锚点:目录导航    -->
          <div
              :key="anchor"
              v-for="anchor in titles"
              :style="{ padding: `10px 0 10px ${anchor.indent * 20}px`}"
              @click="handleAnchorClick(anchor)">
            <a style="cursor: pointer; color: #3faadb">{{ anchor.title }}</a>
          </div>
        </el-card>

其中titles[]存的是文章内容content筛选后的标题(h1~h6),利用querySelectorAll获取所有dom,详细代码:

    getCatalog(){
      const anchors = this.$refs.preview.$el.querySelectorAll('h1,h2,h3,h4,h5,h6');
      const titles = Array.from(anchors).filter((title) => !!title.innerText.trim()); //过滤文本内容不为空的要素
      console.log(titles)
      if (!titles.length) {
        this.titles = [];
        return;
      }
      const hTags = Array.from(new Set(titles.map((title) => title.tagName))).sort();
      this.titles = titles.map((el) => ({
        title: el.innerText,
        lineIndex: el.getAttribute('data-v-md-line'),
        indent: hTags.indexOf(el.tagName),
      }));
    },

点击当行,定位到相应区域:

//标题导航点击
    handleAnchorClick(anchor) {
      const { preview } = this.$refs;
      const { lineIndex } = anchor;
      const heading = preview.$el.querySelector(`[data-v-md-line="${lineIndex}"]`);
      if (heading) {
        // 注意:如果你使用的是编辑组件的预览模式,则这里的方法名改为 previewScrollToTarget
        preview.scrollToTarget({
          target: heading,
          scrollContainer: window,
          top: 60,
        });
      }
    },

前端效果:

3a6b811e57974a9eabc289579b367881.png

发现在滑动文章后,导航也跟着消失,这样的设计非常不友好,于是加上了导航吸顶的效果。

导航吸顶:

<div style="width: 30%;" :class="navBarFixed === true ? 'navBarWrap' :''">

监听页面滚动:

一旦navBarFixed为true,便把:class与navBarWrap相关联;

  mounted() {
    window.addEventListener("scroll", this.watchScroll);  //监听滚动
  },
  methods: {
    //滚动
    watchScroll() {
      var scrollTop =
          window.pageYOffset ||
          document.documentElement.scrollTop ||
          document.body.scrollTop;
      console.log(scrollTop)
      //  当滚动超过 90 时,实现吸顶效果
      if (scrollTop > 90) {
        this.navBarFixed = true;
      } else {
        this.navBarFixed = false;
      }
    },
  }


<style scoped>
.navBarWrap {
  position:fixed;  //固定组件
  right: 0;
  top: 0;
  z-index:999;
}
</style>

效果展示:

8301094f1eee426aa25664ef070b2676.png

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值