unknown
2024-06-07 d523c0f30bceb610e8e0a6f29d1f6c130460121b
src/books/sportsAndHealth/view/components/index.vue
File was renamed from src/books/sportsAndHealth/index.vue
@@ -1,8 +1,10 @@
<template>
  <div class="page-main" @scroll="throttledScrollHandler">
    <div id="searchDomBox" style="display: none">
      <div id="searchContent"></div>
    </div>
    <div
      class="public-sportsAndHealth"
      @mouseup="handleMouseUp"
      :style="{
        fontSize: fontSize ? fontSize + 'px' : '16px',
        transform: `scale(${pageZoom ? pageZoom : 1})`,
@@ -12,57 +14,64 @@
      <front001
        v-if="showCatalogList.indexOf(1) > -1"
        :showPageList="loadPageList"
        :isSearch="isSearch"
      />
      <ChapterOne
        v-if="showCatalogList.indexOf(2) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      />
      <ChapterTwo
        v-if="showCatalogList.indexOf(3) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        @eventPublic="swdtChange"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      />
      <ChapterThree
        v-if="showCatalogList.indexOf(4) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      />
      <ChapterFour
        v-if="showCatalogList.indexOf(5) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      />
      <!-- <ChapterFive
        v-if="showCatalogList.indexOf(6) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        @Upload_initViewer="changeDomViewer"
        :isSearch="isSearch"
      /> -->
      <!-- <chapterSix
        v-if="showCatalogList.indexOf(7) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      /> -->
      <!-- <chapterSeven
        v-if="showCatalogList.indexOf(8) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        @eventPublic="swdtChange"
        :questionData="questionDataMap"
        @eventSwdt="swdtChange"
        @Upload_initViewer="changeDomViewer"
        :isSearch="isSearch"
      /> -->
      <!-- <chapterEight
        v-if="showCatalogList.indexOf(9) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      /> -->
      <!-- <chapterNine
        v-if="showCatalogList.indexOf(10) > -1"
        :showPageList="loadPageList"
        :questionData="questionData"
        :questionData="questionDataMap"
        :isSearch="isSearch"
      /> -->
      <!-- <chapter010
        v-if="showCatalogList.indexOf(11) > -1"
@@ -105,31 +114,29 @@
</template>
<script>
import front001 from "./view/front001";
import ChapterOne from "./view/chapter001";
import ChapterTwo from "./view/chapter002";
import ChapterThree from "./view/testDynaicTable";
import ChapterFour from "./view/testPp";
// import ChapterThree from "./view/chapter003";
// import ChapterFour from "./view/chapter004";
// import ChapterFive from "./view/chapter005";
// import chapterSix from "./view/chapter006";
// import chapterSeven from "./view/chapter007";
// import chapterEight from "./view/chapter008";
// import chapterNine from "./view/chapter009";
// import chapter010 from "./view/chapter010";
// import chapter011 from "./view/chapter011";
// import chapter012 from "./view/chapter012";
// import chapter013 from "./view/chapter013";
// import chapter014 from "./view/chapter014";
// import chapter015 from "./view/chapter015";
// import chapter016 from "./view/chapter016";
// import chapter017 from "./view/chapter017";
// import chapter018 from "./view/chapter018";
import front001 from "./front001";
import ChapterOne from "./chapter001";
import ChapterTwo from "./chapter002";
import ChapterThree from "./testDynaicTable";
import ChapterFour from "./testPp";
// import ChapterFive from "./chapter005";
// import chapterSix from "./chapter006";
// import chapterSeven from "./chapter007";
// import chapterEight from "./chapter008";
// import chapterNine from "./chapter009";
// import chapter010 from "./chapter010";
// import chapter011 from "./chapter011";
// import chapter012 from "./chapter012";
// import chapter013 from "./chapter013";
// import chapter014 from "./chapter014";
// import chapter015 from "./chapter015";
// import chapter016 from "./chapter016";
// import chapter017 from "./chapter017";
// import chapter018 from "./chapter018";
import NoteIcon from "@/assets/images/biji.png";
import _ from "lodash";
import getQuestionList from "@/assets/methods/examination";
import testData from "./js/examinationList";
import testData from "../../js/examinationList";
import Swiper from "swiper/bundle";
import "swiper/swiper-bundle.css";
import Viewer from "viewerjs";
@@ -146,8 +153,9 @@
      observer: null,
      loadPageObserver: null,
      loadPageList: [],
      questionData: {},
      questionDataMap: {},
      renderSignMap: {},
      highlightData: null,
      isSearch: false,
    };
  },
@@ -210,11 +218,21 @@
        },
        // 渲染笔记、高亮、划线
        renderSign: (type, data) => {
          this.renderSign(type, data);
          // 因为调整为页面懒加载,所以渲染标记也需要按照页面进行处理,先储存数据,页面加载完成再渲染对应的标记;
          this.handelSignData(type, data);
          // this.renderSign(type, data);
        },
        // 删除笔记、高亮、划线
        delSign: (data) => {
          this.delSign(data);
        },
        // 全文检索
        searchBookByKeyword: (keyword) => {
          return this.searchTextByPage(keyword);
        },
        // 跳转检索结果位置
        jumpSearchItem: (data) => {
          this.searchItemLocation(data);
        },
      });
    }
@@ -259,6 +277,12 @@
    // }, 1000);
  },
  methods: {
    changeDomViewer() {
      setTimeout(() => {
        this.initViewer();
      }, 500);
    },
    // 滚动监听
    scrollFun(event) {
      // 判断向上滚动还是向下滚动
@@ -337,6 +361,12 @@
    // 处理标记数据
    handelSignData(type, data) {
      if (this.loadPageList.indexOf(Number(data.page)) > -1) {
        // 立即渲染
        this.renderSign(type, data);
      }
      // 储存数据
      if (!this.renderSignMap[type]) this.renderSignMap[type] = {};
      if (!this.renderSignMap[type][data.page])
        this.renderSignMap[type][data.page] = [];
@@ -345,6 +375,10 @@
    // 渲染标记
    renderSign(type, data) {
      // 父层设置禁止渲染标记时不再进行渲染
      if (this.$store.state.qiankun.disableSign) {
        return false;
      }
      const existence = (
        this.container ? this.container : document
      ).querySelector(`[dataid="${data.id}"]`);
@@ -398,6 +432,7 @@
        }
      }
    },
    // 删除标记渲染
    delSign({ ids, type }) {
      if (ids && ids.length) {
@@ -425,6 +460,7 @@
        }
      }
    },
    initObservation() {
      const sections = (
        this.container ? this.container : document
@@ -453,6 +489,7 @@
        }
      });
    },
    initThemeColor() {
      // 获取各种需要主题色的节点
      const colorDom = (
@@ -532,14 +569,7 @@
        }
      });
    },
    getParentWithClass(element, className) {
      while (element.parentElement) {
        element = element.parentElement;
        if (element.classList.contains(className)) {
          return element;
        }
      }
    },
    pageChangeCallback(entries, observer) {
      //entries:代表观察到的目标元素的集合。 observer:代表观察者对象。
      entries.forEach((entry) => {
@@ -555,7 +585,7 @@
          const catalog = catalogDom.getAttribute("num");
          let text = null;
          if (target.querySelector("p")) {
            text = target.querySelector("p").textContent.substring(0, 20);
            text = target.querySelector("p").textContent.substring(0, 50);
          }
          // 返回页码和章节信息
          if (this.$store.state.qiankun && this.$store.state.qiankun.pageChange)
@@ -571,6 +601,7 @@
        }
      });
    },
    loadPageCallback(entries, observer) {
      entries.forEach(async (entry) => {
        if (entry.isIntersecting) {
@@ -581,12 +612,14 @@
              target,
              "chapter"
            );
            // 添加页码
            this.loadPageList.push(Number(page));
            const catalog = catalogDom.getAttribute("num");
            if (!this.questionData[page]) {
            if (!this.questionDataMap[page]) {
              if (testData && testData[catalog]) {
                if (testData[catalog][page]) {
                  if (Array.isArray(testData[catalog][page])) {
                    this.questionData[page] = await getQuestionList(
                      this.questionDataMap[page] = await getQuestionList(
                      page,
                      testData[catalog][page],
                      this.config.activeBook
@@ -600,13 +633,12 @@
                        this.config.activeBook
                      );
                    }
                    this.questionData[page] = obj;
                    this.questionDataMap[page] = obj;
                  }
                }
              }
            }
            // 添加页码
            this.loadPageList.push(Number(page));
            // 渲染这一页的标记
            for (const key in this.renderSignMap) {
              if (this.renderSignMap[key][page]) {
@@ -614,6 +646,36 @@
                  this.renderSign(key, item);
                });
              }
            }
            // 处理高亮
            if (this.highlightData) {
              // 高亮行
              setTimeout(() => {
                // 获取页面所有text节点
                const pageTextList = document.createTreeWalker(target, NodeFilter.SHOW_TEXT);
                // 匹配关键字
                const allPageTextNodes = [];
                let currentNode = pageTextList.nextNode();
                while (currentNode) {
                  allPageTextNodes.push(currentNode);
                  currentNode = pageTextList.nextNode();
                }
                for (let i = 0; i < allPageTextNodes.length; i++) {
                  const textDom = allPageTextNodes[i];
                  let txtIndex = textDom.textContent.indexOf(
                    this.highlightData.txt
                  );
                  if (txtIndex > -1) {
                    textDom.parentNode.style.transition =
                      "background-color 0.8s";
                    textDom.parentNode.scrollIntoView();
                    textDom.parentNode.style.backgroundColor = "#79bbf0";
                    setTimeout(() => {
                      textDom.parentNode.style.backgroundColor = "";
                    }, 1000);
                  }
                }
              }, 100);
            }
            if (this.loadPageList.length > 5) {
              // 超过5页
@@ -623,6 +685,7 @@
        }
      });
    },
    initSwiper() {
      const doms = (
        this.container ? this.container : document
@@ -702,6 +765,7 @@
        });
      }
    },
    initViewer() {
      const doms = (
        this.container ? this.container : document
@@ -718,57 +782,7 @@
        });
      }
    },
    // eslint-disable-next-line
    getParentWithClass(element, className) {
      while (element.parentElement) {
        element = element.parentElement;
        if (element.classList.contains(className)) {
          return element;
        }
      }
    },
    handleMouseUp(e) {
      const selection = (
        this.container ? this.container : window
      ).getSelection();
      const txt = selection.toString();
      if (selection.type != "none" && txt) {
        let node = selection.anchorNode.parentNode;
        let pageHtml = this.getParentWithClass(
          selection.anchorNode,
          "page-box"
        );
        let chapterDom = this.getParentWithClass(
          selection.anchorNode,
          "chapter"
        );
        let chapterNum;
        if (chapterDom) chapterNum = chapterDom.getAttribute("num");
        if (pageHtml) {
          const page = pageHtml.getAttribute("page");
          // 监听选中文本事件,并触发父层方法
          if (this.$store.state.qiankun.windowSelection) {
            this.$store.state.qiankun.windowSelection({
              chapterNum,
              txt,
              page,
              x: e.x,
              y: e.y,
            });
          }
        }
      } else {
        if (this.$store.state.qiankun.windowSelection) {
          this.$store.state.qiankun.windowSelection({
            chapterNum: "",
            txt: "",
            page: "",
            x: e.x,
            y: e.y,
          });
        }
      }
    },
    swdtChange(data) {
      if (this.$store.state.qiankun && this.$store.state.qiankun.chooseWords) {
        this.$store.state.qiankun.chooseWords({
@@ -776,6 +790,132 @@
          data: data.data,
        });
      }
    },
    // 根据关键字全文检索
    searchTextByPage(keyword) {
      const searchResult = [];
      let catalogIndex = 0;
      // 所有章节组件(每本书制作时单独配置)
      const pageData = {
        front001,
        ChapterOne,
        ChapterTwo,
        ChapterThree,
        ChapterFour,
        // ChapterFive,
        // chapterSix,
        // chapterSeven,
        // chapterEight,
        // chapterNine,
        // chapter010,
        // chapter011,
        // chapter012,
        // chapter013,
        // chapter014,
        // chapter015,
        // chapter016,
        // chapter017,
        // chapter018,
      };
      // 遍历所有章节文件
      for (const key in pageData) {
        catalogIndex++;
        let pageComponent, pageExample;
        // 先渲染一次当前章节文件(这时页面的内容为空),获取页码信息
        pageComponent = Vue.extend(pageData[key]);
        pageExample = new pageComponent({
          propsData: {
            showPageList: [],
            questionData: {},
          },
        });
        pageExample.$mount(
          (this.container ? this.container : document).querySelector(
            "#searchContent"
          )
        );
        // 获取页码
        const pageDom = (this.container ? this.container : document)
          .querySelector("#searchDomBox")
          .querySelectorAll(".page-box");
        const pages = [];
        for (let i = 0; i < pageDom.length; i++) {
          const pageDomItem = pageDom[i];
          pages.push(Number(pageDomItem.getAttribute("page")));
        }
        // 获取页面结束,卸载销毁
        pageExample.$destroy();
        (this.container ? this.container : document).querySelector(
          "#searchDomBox"
        ).innerHTML = '<div id="searchContent"></div>';
        // 遍历页码
        if (pages.length) {
          for (let i = 0; i < pages.length; i++) {
            const pageNum = pages[i];
            // 动态渲染对应章节的页码
            pageComponent = Vue.extend(pageData[key]);
            pageExample = new pageComponent({
              propsData: {
                showPageList: [pageNum],
                questionData: {},
              },
            });
            pageExample.$mount(
              (this.container ? this.container : document).querySelector(
                "#searchContent"
              )
            );
            // 获取对应页面dom
            const thisPageDom = (this.container ? this.container : document)
              .querySelector("#searchDomBox")
              .querySelector(`[page="${pageNum}"]`);
            if (thisPageDom) {
              // 获取页面所有text节点
              const pageTextList = document.createTreeWalker(
                thisPageDom,
                NodeFilter.SHOW_TEXT
              );
              // 匹配关键字
              const allPageTextNodes = [];
              let currentNode = pageTextList.nextNode();
              while (currentNode) {
                allPageTextNodes.push(currentNode);
                currentNode = pageTextList.nextNode();
              }
              for (let i = 0; i < allPageTextNodes.length; i++) {
                const textDom = allPageTextNodes[i];
                let txtIndex = textDom.textContent.indexOf(keyword);
                if (txtIndex > -1) {
                  // 记录关键字所在页码、章节以及匹配到的段落
                  searchResult.push({
                    page: pageNum,
                    catalog: catalogIndex,
                    txt: textDom.textContent,
                    txtIndex: txtIndex,
                  });
                }
              }
              // 结束,卸载销毁
              pageExample.$destroy();
              (this.container ? this.container : document).querySelector(
                "#searchDomBox"
              ).innerHTML = '<div id="searchContent"></div>';
            }
          }
        }
      }
      // 输出搜索结果
      // console.log(searchResult);
      return searchResult;
    },
    // 根据检索结果跳转对应位置并高亮
    searchItemLocation(data) {
      // 记录高亮信息
      this.highlightData = data;
      // 跳转
      this.gotoPage(data.catalog, data.page, () => {});
    },
  },
  components: {
@@ -801,7 +941,3 @@
  },
};
</script>
<style lang="less">
@import "./css/default.less";
</style>