页面布局——左侧内容,右侧目录。页面滚动,目录随着active变化

页面如下布局
页面布局
在mounted监测左侧内容滚动

async mounted() {
    this.getCatalogue();  //通过内容标签获取目录
    this.$nextTick(() => {
      document.querySelector("#app").addEventListener("scroll", this.updateLeftNav, false);  // 监听页面的滚动,调用updateLeftNav方法
    });
  }
  beforeDestroy() {
    document.querySelector("#app").removeEventListener("scroll", this.updateLeftNav, false); // 页面的销毁
  }

调用updateLeftNav方法

updateLeftNav(e) {
    let that = this;
    let cardsList = e.target.querySelectorAll("h1,h2,h3");
    let len = cardsList.length;
    if (len) {
      for (let i = len - 1; i >= 1; i--) {
        let num = cardsList[i].getBoundingClientRect().top;
        if (num < 70) {
          if (cardsList[i].getAttribute("id")) {
            that.selectedItemKey = cardsList[i].getAttribute("id");
            return false;
          }
        }
      }
    }
  }

通过内容获取目录

 getCatalogue() {
    //结果集
    let articleDom = this.$refs.articleContent;
    let doms = articleDom.querySelectorAll("h1,h2,h3");
    let hEles = ["h1", "h2", "h3"];
    let catalogue = [];
    let index = 0;
    if (doms.length > 0) {
      doms.forEach((element) => {
        var nodetext = element.innerHTML.replace(/<\/?[^>]+>/g, "");
        nodetext = nodetext.replace(/&nbsp;/g, "");
        let name = element.nodeName.toLowerCase();
        if (hEles.includes(name)) {
          index++;
          let id = `catalogue_${index}`;
          //为当前节点添加id,方便使用瞄点定位
          element.setAttribute("id", id);
          let level = name.replace("h", "");
          catalogue.push({
            id: id,
            key: name,
            title: nodetext,
            level: Number(level),
          });
        }
      });
    }
    this.catalogue = catalogue;
  }

目录展示

 <!-- 右侧目录 -->
        <div class="article-content-right" v-if="catalogue.length > 0">
          <div class="catalogue-cont">
            <div class="tit">
              <h3>目录</h3>
              <span @click="isShow = !isShow">{{ isShow ? "收起" : "展开" }}</span>
            </div>
            <div class="catalogue" v-show="isShow">
              <div
                :class="{
                  defaultColor: true,
                  currentColor: selectedItemKey && item.id == selectedItemKey,
                }"
                v-for="item in catalogue"
                :key="item.id"
                :title="item.title"
              >
                <a :href="`#${item.id}`" @click="handleAnchorClick($event, item.id)">
                  {{ item.title }}
                </a>
              </div>
            </div>
          </div>
        </div>

点击目录页面滚动到对应锚点

 handleAnchorClick(e, href) {
    e.preventDefault();
    if (href) {
      // 找到锚点对应得的节点
      let element = document.getElementById(href);
      // 如果对应id的锚点存在,就跳滚动到锚点顶部

      if (element) {
        scrollToHash(
          element.getBoundingClientRect().top + document.querySelector("#app").scrollTop - 60
        );
      }
      this.selectedItemKey = href;
    }
  }```

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值