动态锚点根据后台返回的数据截取响应部分高亮文本各种颜色

<template>
  <div class="privacy">
    <div class="privacy-upInfo">
      <div class="privacy-upreturn">
        <h3 class="privacy-upreturn-h3">
          <button class="privacy-upreturn-return" @click="privacyReturn">
            返回
          </button>
        </h3>
        <div class="privacy-info">
          <h4>
            文件名称: <span>{{ fileName }}</span>
          </h4>
          <h4>
            审核日期: <span>{{ audioDate }}</span>
          </h4>
        </div>
        <h3 class="privacy-upreturn-infoTitle">
          {{ summary }}
        </h3>
      </div>
    </div>
    <div class="privacy-main clearfix">
      <div class="privacy-main-left">
        <h3 class="left_h3">隐私政策文本</h3>
        <div v-html="textContent" class="privacy-text"></div>
      </div>
      <div class="privacy-main-right">
        <el-menu
          default-active="2"
          class="pass-demo-menu"
          @open="handleOpen"
          @close="handleClose"
          text-color="#333333"
          :unique-opened="true"
          active-text-color="#5D7EDD"
        >
          <el-submenu
            class="textShow"
            v-for="(item, index) in passAssess"
            :key="item.id"
            :disabled="item.titke < 0"
            :index="item.id.toString()"
          >
            <template slot="title">
              <div :title="item.text">
                <i class="el-icon-caret-right"></i>{{ item.text }}
              </div>
            </template>
            <el-menu-item-group v-if="item.sub_title.length > 0">
              <el-menu-item
                v-for="(itemChild, indChild) in item.sub_title"
                :key="indChild"
                v-show="itemChild.text"
                :disabled="
                  !(itemChild.char_in_split.length > 0) &&
                    !(itemChild.split_ids.length > 0)
                "
                :title="itemChild.text"
                :index="index + 1 + '-' + (indChild + 1)"
                @click="gotoParagraph(item, itemChild, 'pass', '')"
                >{{ itemChild.text }}</el-menu-item
              >
            </el-menu-item-group>
          </el-submenu>
        </el-menu>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
export default {
  data() {
    return {
      currentPage: 1,
      privacyDetailId: "",
      fileName: "",
      audioDate: "",
      summary: "",
      colorArr: [
        { bg_color: "#61c073", pg_color: "#61c073" },
        { bg_color: "#f0f26c", pg_color: "#c6c01b" },
        { bg_color: "#89c5fd", pg_color: "#4b8cc9" },
        { bg_color: "#ec7555", pg_color: "#ec7555" },
        { bg_color: "#55ec8e", pg_color: "#37c56c" },
        { bg_color: "#eca355", pg_color: "#de913f" },
        { bg_color: "#ec556e", pg_color: "#ec556e" },
        { bg_color: "#e5f1be", pg_color: "#e5f1be" },
        { bg_color: "#55d5ec", pg_color: "#2da7bd" },
        { bg_color: "#709efc", pg_color: "#709efc" },
      ],
      passAssess: [],
      textContent: "",
      myParagraph: [],
      splitIdArr: [],
    };
  },
  created() {
    this.privacyDetailId = this.$route.query.jumpId;
    this.currentPage = this.$route.query.currentPage || 1;
  },
  mounted() {
    this.initDataDetail();
  },
  methods: {
    async initDataDetail() {
      let params = {
        id: this.privacyDetailId,
      };
      const { resultCode, result } = await this.$api.getPrivacyPolicyDetail(
        params
      );
      const { fileName, updateTime, jsonData, summary, htmlFilePath } = result;
      this.summary = summary;
      this.fileName = fileName;
      this.audioDate = updateTime;
      this.passAssess = jsonData.titles;

      if (process.env.NODE_ENV == "privacyPolicy") {
        // 本地环境打开
        this.htmlFile(
          `http://192.168.1.84/policy-audit/resoure/html/` + htmlFilePath
        );
      } else {
        // 线上环境打开
        this.htmlFile(
          `${window.location.origin}/policy-audit/resoure/html/` + htmlFilePath
        );
      }
    },
    privacyReturn() {
      // this.$router.go(-1);
      this.$router.push({
        path: "/privacyPolicyList",
        query: { currentPage: this.currentPage },
      });
    },
    async htmlFile(url) {
      let param = {
        accept: "text/html, text/plain",
      };
      await axios.get(url, param).then((res) => {
        this.textContent = res.data;
      });
    },
    handleOpen(key, keyPath) {
      let item = "",
        char_in_split = [],
        split_ids = [],
        passProject = this.passAssess[key].sub_title,
        itemChild = {},
        titles = "";
      titles = this.passAssess[key].title;
      for (var i = 0; i < passProject.length; i++) {
        split_ids = split_ids.concat(passProject[i].split_ids.sort());
        char_in_split = char_in_split.concat(passProject[i].char_in_split);
      }
      itemChild = {
        char_in_split: char_in_split,
        split_ids: Array.from(new Set(split_ids)),
      };
      this.gotoParagraph(this.passAssess[key], itemChild, "pass", titles);
    },
    handleClose(key, keyPath) {
      this.handleOpen(key, keyPath);
    },
    gotoParagraph(item, itemChild, passer, titles) {
      //锚点定位
      var paragraph = "";
      if (this.splitIdArr.length > 0) {
        for (var k = 0; k < this.splitIdArr.length; k++) {
          document.querySelector(
            `.span_${this.splitIdArr[k]}`
          ).innerHTML = document
            .querySelector(`.span_${this.splitIdArr[k]}`)
            .innerHTML.replace(/(<([^>]+)>)/g, "");
        }
      }
      this.splitIdArr = [];
      if (this.myParagraph.length > 0) {
        for (var i = 0; i < this.myParagraph.length; i++) {
          document
            .querySelector(`.span_${this.myParagraph[i]}`)
            .classList.remove("pass");
        }
      }
      // 内容截取标记
      if (itemChild.char_in_split && itemChild.char_in_split.length > 0) {
        paragraph = document.querySelector(
          `.span_${
            itemChild.char_in_split[0].split_id > itemChild.split_ids[0]
              ? itemChild.split_ids[0]
              : itemChild.char_in_split[0].split_id
          }`
        );

        for (var j = 0; j < itemChild.char_in_split.length; j++) {
          let { split_id, elements } = itemChild.char_in_split[j];
          this.splitIdArr.push(split_id);
          if (split_id) {
            var strList = "";
            let str = document
              .querySelector(`.span_${split_id}`)
              .innerHTML.replace(/(<([^>]+)>)/g, "");
            strList = str.split("");
            if (elements.length > 0) {
              for (var i = 0; i < elements.length; i++) {
                var { start, end, type } = elements[i];
                if (start == end - 1) {
                  strList[start] = `<em style="background:${
                    this.colorFun(type).bg_color
                  };color:#454545;" class="bg_colors">${str[start]}</em>`;
                } else {
                  strList[start] = `<em style="background:${
                    this.colorFun(type).bg_color
                  };color:#454545;" class="bg_colors">${str[start]}`;
                  strList[end - 1] = `${str[end - 1]}</em>`;
                }
              }
              document.querySelector(
                `.span_${split_id}`
              ).innerHTML = strList.join("");
            }
          }
        }
      }
      // 段落标记
      if (itemChild.split_ids && itemChild.split_ids.length > 0) {
        if (itemChild.char_in_split && itemChild.char_in_split.length > 0) {
          paragraph = document.querySelector(
            `.span_${
              itemChild.char_in_split[0].split_id > itemChild.split_ids[0]
                ? itemChild.split_ids[0]
                : itemChild.char_in_split[0].split_id
            } `
          );
        } else {
          paragraph = document.querySelector(
            `.span_${itemChild.split_ids[0]} `
          );
        }
        this.myParagraph = itemChild.split_ids;
        for (var k = 0; k < itemChild.split_ids.length; k++) {
          if (passer == "pass") {
            document
              .getElementsByClassName(`span_${itemChild.split_ids[k]}`)[0]
              .classList.add("pass");
          }
        }
      } else {
        this.myParagraph = [];
      }
      //  锚点
      if (titles) {
        paragraph = document.querySelector(`.span_${[titles]}`);
      }
      if (paragraph) {
        paragraph.scrollIntoView({
          behavior: "smooth",
          block: "start",
          inline: "start",
        });
      }
    },
    colorFun(type) {
      let pgcolorName = "";
      let bgcolorName = "";
      if (type == "PI" || type == "PP" || type == "SI") {
        pgcolorName = this.colorArr[0].pg_color;
        bgcolorName = this.colorArr[0].bg_color;
      } else if (type == "BF" || type == "SN" || type == "CN") {
        pgcolorName = this.colorArr[1].pg_color;
        bgcolorName = this.colorArr[1].bg_color;
      } else if (type == "RA" || type == "CI" || type == "PC") {
        pgcolorName = this.colorArr[2].pg_color;
        bgcolorName = this.colorArr[2].bg_color;
      } else if (type == "RE" || type == "PE") {
        pgcolorName = this.colorArr[3].pg_color;
        bgcolorName = this.colorArr[3].bg_color;
      } else if (type == "UN-PUR" || type == "UN-MC" || type == "UN-SL") {
        pgcolorName = this.colorArr[4].pg_color;
        bgcolorName = this.colorArr[4].bg_color;
      } else if (type == "UN-LOC" || type == "UN-TRE" || type == "UN-PRO") {
        pgcolorName = this.colorArr[5].pg_color;
        bgcolorName = this.colorArr[5].bg_color;
      } else if (type == "UN-ABL" || type == "UN-NOT" || type == "UN-LIM") {
        pgcolorName = this.colorArr[6].pg_color;
        bgcolorName = this.colorArr[6].bg_color;
      } else if (type == "UN-COO" || type == "UN-EXC3" || type == "UN-EXC4") {
        pgcolorName = this.colorArr[7].pg_color;
        bgcolorName = this.colorArr[7].bg_color;
      } else if (type == "UN-UPD" || type == "UN-WT" || type == "UN-UNOT") {
        pgcolorName = this.colorArr[8].pg_color;
        bgcolorName = this.colorArr[8].bg_color;
      }
      return { pg_color: pgcolorName, bg_color: bgcolorName };
    },
  },
};
</script>
<style lang="scss" scope>
.disabled {
  pointer-events: none;
  cursor: default;
  opacity: 0.6;
}
.privacy {
  &-upInfo {
    box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);
    border-radius: 4px;
  }
  &-upreturn {
    overflow: hidden;
    background: rgba(255, 255, 255, 1);
    border: 1px solid rgba(235, 237, 242, 1);
    &-h3 {
      width: 120px;
      height: 36px;
      margin-top: 30px;
      float: left;
      border-right: 1px solid #dddddd;
    }
    &-return {
      width: 78px;
      height: 36px;
      background: rgba(47, 127, 227, 1);
      box-shadow: 0px 2px 7px 0px rgba(47, 127, 227, 0.5);
      border-radius: 2px;
      border: rgba(47, 127, 227, 1);
      outline: none;
      cursor: pointer;
      color: #fff;
      float: left;
      margin-left: 22px;
      padding-left: 22px;
      position: relative;
      &::after {
        content: "";
        position: absolute;
        display: block;
        height: 20px;
        width: 12px;
        top: 8px;
        left: 14px;
        background: url("../../assets/images/privacy/return.png") no-repeat left
          center;
      }
    }
    &-infoTitle {
      float: right;
      font-size: 16px;
      color: #454545;
      height: 30px;
      margin: 40px 192px 0 0;
      line-height: 30px;
      text-indent: 23px;
      margin-left: 20px;
    }
  }
  &-info {
    float: left;
    background: rgba(255, 255, 255, 1);
    padding: 24px 0 20px 0;
    h4 {
      margin: 0 0 0 31px;
      font-size: 16px;
      height: 16px;
      line-height: 16px;
      color: #333333;
      &:first-child {
        margin-bottom: 20px;
      }
      span {
        font-weight: normal;
        margin-left: 17px;
      }
    }
  }
  &-main {
    border-radius: 4px;
    height: calc(100vh - 232px);
    width: 100%;
    margin-top: 20px;
    &-left {
      float: left;
      width: calc(100% - 460px);
      height: 100%;
      background: rgba(255, 255, 255, 1);
      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);
      box-sizing: border-box;
      padding: 0 20px 0 30px;
      font-family: "微软雅黑", PingFang-SC-Regular, Helvetica, sans-serif;
      overflow: auto;
      h3 {
        font-size: 16px;
        border-left: 5px solid #5d7edd;
        text-indent: 9px;
        margin-bottom: 18px;
        margin-top: 30px;
        color: #333333;
      }
      .privacy-text {
        & > div {
          width: 100% !important;
          margin: 0 !important;
        }
        .pass {
          border: 1px solid #5d7edd;
          color: #5d7edd;
          padding: 2px 0;
        }
        p {
          line-height: 1.5em;
          margin-top: 1.5em;
        }
        em {
          font-style: normal;
        }
        .bg_colors {
          font-style: normal;
        }
      }
    }
    &-right {
      float: right;
      width: 440px;
      height: 100%;
      background: #fff;
      overflow: auto;
      box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);
      box-sizing: border-box;
      padding: 25px 35px 11px 27px;
      .el-menu {
        border-right: none !important;
        background: rgba(237, 241, 245, 1);
        .is-opened {
          .el-icon-caret-right:before {
            content: ":";
          }
          .el-icon-caret-right:before {
            content: "\e790";
          }
        }
        .el-submenu {
          .el-menu-item {
            padding: 0 20px 0 50px !important;
            text-overflow: ellipsis;
            overflow: hidden;
          }
          .el-menu-item-group__title {
            padding: 0 !important;
          }
          .el-submenu__title {
            padding: 0 20px 0 20px !important;
            font-size: 14px !important;
            & > div {
              white-space: nowrap;
              text-overflow: ellipsis;
              overflow: hidden;
              vertical-align: middle;
            }
            .el-icon-caret-left {
              font-size: 14px;
            }
            .el-submenu__icon-arrow {
              display: none;
            }
          }
          .el-menu--inline {
            background: #f9fdff;
          }
        }
      }
      h3 {
        margin: 0;
        font-size: 16px;
        border-left: 5px solid #5d7edd;
        text-indent: 9px;
        margin-bottom: 18px;
        &:nth-of-type(2) {
          margin-top: 31px;
        }
      }
    }
  }
}
</style>

动态锚点根据后台返回的数据截取响应部分高亮文本各种颜色

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值