Browse Source

滚动联动调整

zhangjie 2 years ago
parent
commit
8158e0430e

+ 5 - 1
src/components/vEditor/VEditor.vue

@@ -17,7 +17,7 @@
           contenteditable
           :style="styles"
           @input="emitJSON"
-          @focus="isFocus = true"
+          @focus="editorFocus"
           @blur="editorBlur"
         ></div>
       </div>
@@ -317,6 +317,10 @@ export default {
       this.clearActiveImg();
       this.clearResizeDom();
     },
+    editorFocus() {
+      this.isFocus = true;
+      this.$emit("focus");
+    },
   },
 };
 </script>

+ 9 - 175
src/modules/question/components/QuestionImportEdit.vue

@@ -61,6 +61,7 @@
                     custom-emit-input
                     :custom-render-action="renderRichText"
                     :custom-tojson-action="richTextToJSON"
+                    @focus="() => richTextFocus(richJsonItem)"
                   ></v-editor>
                   <div
                     v-if="richJsonItem.exceptions.length"
@@ -157,6 +158,7 @@ import { QUESTION_API } from "@/constants/constants";
 import { propertyNameQueryApi } from "@/modules/question/api";
 import { downloadByApi } from "@/plugins/download";
 import { richTextToJSON, renderRichText } from "./import-edit/richText";
+import scrollMixins from "./import-edit/scrollMixins";
 
 const questionInfoField = [
   "courseId",
@@ -172,6 +174,7 @@ const questionInfoField = [
 export default {
   name: "QuestionImportEdit",
   components: { QuestionImportPaperEdit, ImportFileDialog, UploadButton },
+  mixins: [scrollMixins],
   props: {
     data: {
       type: Object,
@@ -223,6 +226,7 @@ export default {
       //   detailInfo: paperParseData,
       // });
       this.resetData(this.data);
+      console.log(this);
 
       this.$nextTick(() => {
         this.registScrollEvent();
@@ -375,6 +379,7 @@ export default {
       }
 
       groups.forEach((group) => {
+        group.indexs = group.sections.map((item) => item.remark.index);
         group.exceptions = group.sections
           .filter((section) => !section.remark.status)
           .map((section) => section.remark.cause);
@@ -851,186 +856,15 @@ export default {
     uploadError(error) {
       this.$message.error(error.message);
     },
-    // scroll
-    registScrollEvent() {
-      document
-        .getElementById("qe-part-paper")
-        .addEventListener("scroll", this.paperScrollEvent);
-      document
-        .getElementById("qe-part-richtext-list")
-        .parentNode.addEventListener("scroll", this.richTextScrollEvent);
-    },
-    removeScrollEvent() {
-      document
-        .getElementById("qe-part-paper")
-        .removeEventListener("scroll", this.paperScrollEvent);
-      document
-        .getElementById("qe-part-richtext-list")
-        .parentNode.removeEventListener("scroll", this.richTextScrollEvent);
-    },
-    paperScrollEvent(e) {
-      // e.preventDefault();
-      // e.stopPropagation();
-      if (this.scrollType === "rich-text") {
-        this.lastPaperScrollTop =
-          document.getElementById("qe-part-paper").scrollTop;
-        return;
-      }
-      this.scrollType = "paper";
-      setTimeout(() => {
-        this.scrollType = "";
-      }, 100);
-      const questionContIndexList =
-        this.$refs.QuestionImportPaperEdit.questionContIndexList;
-
-      const scrollTop = e.target.scrollTop;
-      const isScrollDown = scrollTop > this.lastPaperScrollTop;
-      this.lastPaperScrollTop = scrollTop;
-      const targeContIndex = questionContIndexList.findIndex(
-        (item) => scrollTop < item[3]
-      );
-      let targeContPercent = 0;
-      let targeCont = null;
-      let nextTargetCont = null;
-      if (targeContIndex !== -1) {
-        targeCont = questionContIndexList[targeContIndex - 1];
-        nextTargetCont = questionContIndexList[targeContIndex];
-        targeContPercent =
-          (scrollTop - targeCont[3]) / (nextTargetCont[3] - targeCont[3]);
-      } else {
-        targeCont = questionContIndexList.slice(-1)[0];
-        const textHeight = this.$refs.QuestionImportPaperEdit.$el.offsetHeight;
-        targeContPercent =
-          (scrollTop - targeCont[3]) / (textHeight - targeCont[3]);
-      }
-
-      const richTextSectionDom = document.getElementById(
-        `section-${targeCont[2][0]}`
+    // rich test editor
+    richTextFocus(richTextGroup) {
+      this.$refs.QuestionImportPaperEdit.scrollToContentByIndex(
+        richTextGroup.indexs
       );
-      if (!richTextSectionDom) return;
-
-      const richTextListDom = document.getElementById("qe-part-richtext-list");
-      const elPos = richTextListDom.getBoundingClientRect();
-      const richTextContainerDom = richTextListDom.parentNode;
-
-      const sectionOffsetTop =
-        richTextSectionDom.getBoundingClientRect().y - elPos.y;
-      let nextSectionOffsetTop = richTextListDom.offsetHeight;
-
-      if (nextTargetCont) {
-        const nextRichTextSectionDom = document.getElementById(
-          `section-${nextTargetCont[2][0]}`
-        );
-        if (nextRichTextSectionDom) {
-          nextSectionOffsetTop =
-            nextRichTextSectionDom.getBoundingClientRect().y - elPos.y;
-        } else {
-          nextSectionOffsetTop =
-            richTextSectionDom.offsetTop + richTextSectionDom.offsetHeight;
-        }
-      }
-
-      const textScrollTop =
-        sectionOffsetTop +
-        targeContPercent * (nextSectionOffsetTop - sectionOffsetTop);
-      // console.log(
-      //   targeCont[2],
-      //   textScrollTop,
-      //   targeContPercent,
-      //   nextSectionOffsetTop,
-      //   sectionOffsetTop
-      // );
-      richTextContainerDom.scrollTop = isScrollDown
-        ? Math.max(textScrollTop, richTextContainerDom.scrollTop)
-        : Math.min(textScrollTop, richTextContainerDom.scrollTop);
-    },
-    richTextScrollEvent(e) {
-      if (this.scrollType === "paper") {
-        this.lastRichTextScrollTop = document.getElementById(
-          "qe-part-richtext-list"
-        ).parentNode.scrollTop;
-        return;
-      }
       this.scrollType = "rich-text";
       setTimeout(() => {
         this.scrollType = "";
       }, 100);
-
-      const isScrollDown = e.target.scrollTop > this.lastRichTextScrollTop;
-      // console.log(isScrollDown, e.target.scrollTop, this.lastRichTextScrollTop);
-      this.lastRichTextScrollTop = e.target.scrollTop;
-      const offsetH = isScrollDown ? 150 : 0;
-      const scrollTop = e.target.scrollTop + offsetH;
-
-      const richTextListDom = document.getElementById("qe-part-richtext-list");
-
-      const questionContIndexList =
-        this.$refs.QuestionImportPaperEdit.questionContIndexList;
-
-      const findQuestionItemDom = (sectionIndex) => {
-        const questionCont = questionContIndexList.find((item) =>
-          item[2].includes(sectionIndex)
-        );
-        if (!questionCont) return;
-        const [id, type] = questionCont;
-        let itemDom = document.getElementById(id);
-        if (type === "body") {
-          itemDom = itemDom.querySelector(".ep-question-title");
-        } else if (type === "option") {
-          itemDom = itemDom.querySelector(".ep-question-body");
-        } else if (type === "answer") {
-          itemDom =
-            itemDom.querySelector(".question-info-view") ||
-            itemDom.querySelector(".ep-question-props");
-        }
-        return itemDom;
-      };
-
-      const targeContIndex = this.richTextIndexList.findIndex(
-        (item) => scrollTop < item[1]
-      );
-      if (!targeContIndex) return;
-      let targeContPercent = 0;
-      let targeCont = null;
-      let nextTargetCont = null;
-      if (targeContIndex !== -1) {
-        targeCont = this.richTextIndexList[targeContIndex - 1];
-        nextTargetCont = this.richTextIndexList[targeContIndex];
-        targeContPercent =
-          (scrollTop - targeCont[1]) / (nextTargetCont[1] - targeCont[1]);
-      } else {
-        targeCont = this.richTextIndexList.slice(-1)[0];
-        const textHeight = richTextListDom.offsetHeight;
-        targeContPercent =
-          (scrollTop - targeCont[1]) / (textHeight - targeCont[1]);
-      }
-
-      const questionContDom = findQuestionItemDom(targeCont[0]);
-      if (!questionContDom) return;
-      const questionListDom = this.$refs.QuestionImportPaperEdit.$el;
-      const elPos = questionListDom.getBoundingClientRect();
-      const questionPos = questionContDom.getBoundingClientRect();
-      const questionContOffsetTop = questionPos.y - elPos.y;
-      let nextQuestionContOffsetTop = questionListDom.offsetHeight;
-
-      if (nextTargetCont) {
-        const nextQuestionContDom = findQuestionItemDom(nextTargetCont[0]);
-        if (nextQuestionContDom) {
-          const nextQuestionPos = nextQuestionContDom.getBoundingClientRect();
-          nextQuestionContOffsetTop = nextQuestionPos.y - elPos.y;
-        } else {
-          nextQuestionContOffsetTop =
-            questionContOffsetTop + questionContDom.offsetHeight;
-        }
-      }
-
-      const questionScrollTop =
-        questionContOffsetTop +
-        targeContPercent * (nextQuestionContOffsetTop - questionContOffsetTop);
-      const questionContainerDom = document.getElementById("qe-part-paper");
-      questionContainerDom.scrollTop = isScrollDown
-        ? Math.max(questionScrollTop, questionContainerDom.scrollTop)
-        : Math.min(questionScrollTop, questionContainerDom.scrollTop);
     },
   },
 };

+ 10 - 0
src/modules/question/components/QuestionImportPaperEdit.vue

@@ -207,6 +207,16 @@ export default {
     questionActive(question) {
       this.activeQuestionId = question.id;
     },
+    scrollToContentByIndex(indexs) {
+      const questionCont = this.questionContIndexList.find((item) =>
+        indexs.some((ind) => item[2].includes(ind))
+      );
+      const questionContDom = document.getElementById(questionCont[0]);
+      const elPos = this.$el.getBoundingClientRect();
+      const itemPos = questionContDom.getBoundingClientRect();
+      const questionContOffsetTop = itemPos.y - elPos.y;
+      this.$el.parentNode.scrollTop = questionContOffsetTop - 50;
+    },
   },
 };
 </script>

+ 185 - 0
src/modules/question/components/import-edit/scrollMixins.js

@@ -0,0 +1,185 @@
+export default {
+  methods: {
+    registScrollEvent() {
+      document
+        .getElementById("qe-part-paper")
+        .addEventListener("scroll", this.paperScrollEvent);
+      document
+        .getElementById("qe-part-richtext-list")
+        .parentNode.addEventListener("scroll", this.richTextScrollEvent);
+    },
+    removeScrollEvent() {
+      document
+        .getElementById("qe-part-paper")
+        .removeEventListener("scroll", this.paperScrollEvent);
+      document
+        .getElementById("qe-part-richtext-list")
+        .parentNode.removeEventListener("scroll", this.richTextScrollEvent);
+    },
+    paperScrollEvent(e) {
+      // e.preventDefault();
+      // e.stopPropagation();
+      if (this.scrollType === "rich-text") {
+        this.lastPaperScrollTop =
+          document.getElementById("qe-part-paper").scrollTop;
+        return;
+      }
+      this.scrollType = "paper";
+      setTimeout(() => {
+        this.scrollType = "";
+      }, 100);
+
+      const questionContIndexList =
+        this.$refs.QuestionImportPaperEdit.questionContIndexList;
+
+      const scrollTop = e.target.scrollTop;
+      const isScrollDown = scrollTop > this.lastPaperScrollTop;
+      this.lastPaperScrollTop = scrollTop;
+      const targeContIndex = questionContIndexList.findIndex(
+        (item) => scrollTop < item[3]
+      );
+      let targeContPercent = 0;
+      let targeCont = null;
+      let nextTargetCont = null;
+      if (targeContIndex !== -1) {
+        targeCont = questionContIndexList[targeContIndex - 1];
+        nextTargetCont = questionContIndexList[targeContIndex];
+        targeContPercent =
+          (scrollTop - targeCont[3]) / (nextTargetCont[3] - targeCont[3]);
+      } else {
+        targeCont = questionContIndexList.slice(-1)[0];
+        const textHeight = this.$refs.QuestionImportPaperEdit.$el.offsetHeight;
+        targeContPercent =
+          (scrollTop - targeCont[3]) / (textHeight - targeCont[3]);
+      }
+
+      const richTextSectionDom = document.getElementById(
+        `section-${targeCont[2][0]}`
+      );
+      if (!richTextSectionDom) return;
+
+      const richTextListDom = document.getElementById("qe-part-richtext-list");
+      const elPos = richTextListDom.getBoundingClientRect();
+      const richTextContainerDom = richTextListDom.parentNode;
+
+      const sectionOffsetTop =
+        richTextSectionDom.getBoundingClientRect().y - elPos.y;
+      let nextSectionOffsetTop = richTextListDom.offsetHeight;
+
+      if (nextTargetCont) {
+        const nextRichTextSectionDom = document.getElementById(
+          `section-${nextTargetCont[2][0]}`
+        );
+        if (nextRichTextSectionDom) {
+          nextSectionOffsetTop =
+            nextRichTextSectionDom.getBoundingClientRect().y - elPos.y;
+        } else {
+          nextSectionOffsetTop =
+            richTextSectionDom.offsetTop + richTextSectionDom.offsetHeight;
+        }
+      }
+
+      const textScrollTop =
+        sectionOffsetTop +
+        targeContPercent * (nextSectionOffsetTop - sectionOffsetTop);
+      // console.log(
+      //   targeCont[2],
+      //   textScrollTop,
+      //   targeContPercent,
+      //   nextSectionOffsetTop,
+      //   sectionOffsetTop
+      // );
+      richTextContainerDom.scrollTop = isScrollDown
+        ? Math.max(textScrollTop, richTextContainerDom.scrollTop)
+        : Math.min(textScrollTop, richTextContainerDom.scrollTop);
+    },
+    richTextScrollEvent(e) {
+      if (this.scrollType === "paper") {
+        this.lastRichTextScrollTop = document.getElementById(
+          "qe-part-richtext-list"
+        ).parentNode.scrollTop;
+        return;
+      }
+      this.scrollType = "rich-text";
+      setTimeout(() => {
+        this.scrollType = "";
+      }, 100);
+
+      const isScrollDown = e.target.scrollTop > this.lastRichTextScrollTop;
+      // console.log(isScrollDown, e.target.scrollTop, this.lastRichTextScrollTop);
+      this.lastRichTextScrollTop = e.target.scrollTop;
+      const offsetH = isScrollDown ? 150 : 0;
+      const scrollTop = e.target.scrollTop + offsetH;
+
+      const richTextListDom = document.getElementById("qe-part-richtext-list");
+
+      const questionContIndexList =
+        this.$refs.QuestionImportPaperEdit.questionContIndexList;
+
+      const findQuestionItemDom = (sectionIndex) => {
+        const questionCont = questionContIndexList.find((item) =>
+          item[2].includes(sectionIndex)
+        );
+        if (!questionCont) return;
+        const [id, type] = questionCont;
+        let itemDom = document.getElementById(id);
+        if (type === "body") {
+          itemDom = itemDom.querySelector(".ep-question-title");
+        } else if (type === "option") {
+          itemDom = itemDom.querySelector(".ep-question-body");
+        } else if (type === "answer") {
+          itemDom =
+            itemDom.querySelector(".question-info-view") ||
+            itemDom.querySelector(".ep-question-props");
+        }
+        return itemDom;
+      };
+
+      const targeContIndex = this.richTextIndexList.findIndex(
+        (item) => scrollTop < item[1]
+      );
+      if (!targeContIndex) return;
+      let targeContPercent = 0;
+      let targeCont = null;
+      let nextTargetCont = null;
+      if (targeContIndex !== -1) {
+        targeCont = this.richTextIndexList[targeContIndex - 1];
+        nextTargetCont = this.richTextIndexList[targeContIndex];
+        targeContPercent =
+          (scrollTop - targeCont[1]) / (nextTargetCont[1] - targeCont[1]);
+      } else {
+        targeCont = this.richTextIndexList.slice(-1)[0];
+        const textHeight = richTextListDom.offsetHeight;
+        targeContPercent =
+          (scrollTop - targeCont[1]) / (textHeight - targeCont[1]);
+      }
+
+      const questionContDom = findQuestionItemDom(targeCont[0]);
+      if (!questionContDom) return;
+      const questionListDom = this.$refs.QuestionImportPaperEdit.$el;
+      const elPos = questionListDom.getBoundingClientRect();
+      const questionPos = questionContDom.getBoundingClientRect();
+      const questionContOffsetTop = questionPos.y - elPos.y;
+      let nextQuestionContOffsetTop = questionListDom.offsetHeight;
+
+      if (nextTargetCont) {
+        const nextQuestionContDom = findQuestionItemDom(nextTargetCont[0]);
+        if (nextQuestionContDom) {
+          const nextQuestionPos = nextQuestionContDom.getBoundingClientRect();
+          nextQuestionContOffsetTop = nextQuestionPos.y - elPos.y;
+        } else {
+          nextQuestionContOffsetTop =
+            questionContOffsetTop + questionContDom.offsetHeight;
+        }
+      }
+
+      const questionScrollTop =
+        questionContOffsetTop +
+        targeContPercent * (nextQuestionContOffsetTop - questionContOffsetTop);
+      const questionContainerDom = document.getElementById("qe-part-paper");
+      questionContainerDom.scrollTop = isScrollDown
+        ? Math.max(questionScrollTop, questionContainerDom.scrollTop)
+        : Math.min(questionScrollTop, questionContainerDom.scrollTop);
+    },
+  },
+};