Browse Source

连线题去掉图片放大功能,图片和文字居中,图片默认居左,图片大小修改为自定义横宽比

dusenyao 1 year ago
parent
commit
b65de22b7a
1 changed files with 40 additions and 71 deletions
  1. 40 71
      src/views/exercise_questions/preview/MatchingPreview.vue

+ 40 - 71
src/views/exercise_questions/preview/MatchingPreview.vue

@@ -40,7 +40,7 @@
 
     <div v-if="isShowRightAnswer" class="right-answer">
       <div class="title">正确答案</div>
-      <ul ref="answer-list" class="option-list">
+      <ul ref="answerList" class="option-list">
         <li v-for="(item, i) in optionList" :key="i" class="list-item">
           <div v-for="{ content, mark } in item" :key="mark" :class="['item-wrapper', `answer-item-${mark}`]">
             <span class="content rich-text" v-html="sanitizeHTML(content)"></span>
@@ -102,19 +102,30 @@ export default {
     },
   },
   watch: {
-    optionList: {
-      handler(val) {
-        this.clearLine();
-        if (!val) return;
-        let list = this.optionList.map((item) => {
-          return item.map(({ mark }) => {
-            return { mark, preMark: '', nextMark: '' };
+    optionList: [
+      {
+        handler(val) {
+          this.clearLine();
+          if (!val) return;
+          let list = this.optionList.map((item) => {
+            return item.map(({ mark }) => {
+              return { mark, preMark: '', nextMark: '' };
+            });
           });
-        });
-        this.$set(this, 'answerList', list);
+          this.$set(this, 'answerList', list);
+        },
+        immediate: true,
       },
-      immediate: true,
-    },
+      {
+        handler(val) {
+          if (!val) return;
+          this.$nextTick(() => {
+            this.judgeRichTextIsImgAndText();
+          });
+        },
+        deep: true,
+      },
+    ],
     answerList: {
       handler(list) {
         let arr = [];
@@ -182,6 +193,7 @@ export default {
       if (cur) {
         this.$nextTick(() => {
           this.circulateAnswerList(true);
+          this.judgeRichTextIsImgAndText(true);
         });
       }
     },
@@ -190,13 +202,13 @@ export default {
     document.addEventListener('click', this.handleEventConnection);
     document.addEventListener('mousemove', this.documentMousemouse);
     document.addEventListener('mouseup', this.documentMouseup);
-    this.$refs.list.addEventListener('mouseover', this.imgCloneEvent);
+    this.judgeRichTextIsImgAndText();
+    this.judgeRichTextIsImgAndText(true);
   },
   beforeDestroy() {
     document.removeEventListener('click', this.handleEventConnection);
     document.removeEventListener('mousemove', this.documentMousemouse);
     document.removeEventListener('mouseup', this.documentMouseup);
-    this.$refs.list.removeEventListener('mouseover', this.imgCloneEvent);
   },
   methods: {
     /* 用 mouse 事件模拟拖拽 开始*/
@@ -389,7 +401,7 @@ export default {
       path.setAttribute('d', `M ${size ? 0 : width} 0 L ${size ? width : 0} ${height}`); // 设置路径数据
       this.setPathAttr(path);
       svg.appendChild(path);
-      this.$refs[isShowRightAnswer ? 'answer-list' : 'list'].appendChild(svg); // 将SVG元素插入到文档中
+      this.$refs[isShowRightAnswer ? 'answerList' : 'list'].appendChild(svg); // 将SVG元素插入到文档中
 
       // 清除当前连线点
       this.resetCurConnectionPoint();
@@ -536,57 +548,20 @@ export default {
       }
       return false;
     },
-    // 鼠标进入 ref list 里的元素时,部署进入 img 元素的事件
-    imgCloneEvent(e) {
-      // 元素是 img 且不是 img-clone 时,复制 img 元素
-      if (e.target.tagName === 'IMG' && !e.target.classList.contains('img-clone')) {
-        let imgNatrueWidth = e.target.naturalWidth; // 图片的原始宽度
-        // 将复制的图片显示到 item-wrapper 中
-        // 向上查找父元素,直到找到 item-wrapper
-        let parentNode = e.target.parentNode;
-        while (parentNode && !parentNode.classList.contains('item-wrapper')) {
-          parentNode = parentNode.parentNode;
-        }
-        // 获取 parentNode 距离左侧的距离
-        let parentNodeOffsetLeft = parentNode.offsetLeft + 64;
-        let div = document.createElement('div');
-        let left = e.target.offsetLeft;
-        let width = e.target.width;
-        // 获取预览区域
-        let preview = document.querySelector('.matching-preview');
-        let previewWidth = preview.offsetWidth;
-        // 宽度剩余距离 = 预览区域宽度 - 图片的原始宽度 - 父元素距离左侧的距离 - 图片的宽度 - 图片距离父元素的左边距 - 复制的图片需要距离原图片的宽度
-        let widthExceed = previewWidth - imgNatrueWidth - parentNodeOffsetLeft - width - left - 12;
-        // 判断图片宽度是否超出预览区域
-        if (widthExceed < 0) {
-          let imgLeft =
-            previewWidth - parentNodeOffsetLeft > imgNatrueWidth
-              ? 24
-              : previewWidth - imgNatrueWidth - parentNodeOffsetLeft - 12;
-          div.style = `position: absolute; top: 100%; left: ${imgLeft}px; z-index: 100;`;
-        } else {
-          div.style = `position: absolute; top: 0px; left: ${left + width + 16}px; z-index: 100;`;
-        }
-        // 复制 img 元素
-        let img = e.target.cloneNode();
-        img.classList.add('img-clone');
-        img.style = 'border-radius: 8px;';
-        img.style.objectFit = 'scale-down';
-        // 去掉图片的 width 和 height 属性
-        img.removeAttribute('width');
-        img.removeAttribute('height');
-        div.appendChild(img);
-        let content = document.querySelector('.preview-content') ?? document.querySelector('.answer-container');
-        // 判断scrollTop 是否已到底部
-        if (content.scrollHeight - content.scrollTop === content.clientHeight) {
-          content.scrollTop -= 1;
+    /**
+     * 判断富文本是否包含图片和文本,如果图片和文本都存在,则居中显示
+     * @param {boolean} isAnswer 是否是答案
+     */
+    judgeRichTextIsImgAndText(isAnswer) {
+      let list = isAnswer ? this.$refs.answerList : this.$refs.list;
+      if (!list) return;
+      list.querySelectorAll('.content.rich-text > p').forEach((el) => {
+        let hasTextNode = Array.from(el.childNodes).some((node) => node.nodeType === Node.TEXT_NODE); // 判断是否有文本节点
+        let hasImgNode = Array.from(el.childNodes).some((node) => node.nodeName === 'IMG'); // 判断是否有图片节点
+        if (hasTextNode && hasImgNode) {
+          el.style.textAlign = 'center';
         }
-        parentNode.appendChild(div);
-        // 鼠标移出 div 元素时,删除 div 元素
-        e.target.addEventListener('mouseout', () => {
-          div.remove();
-        });
-      }
+      });
     },
   },
 };
@@ -642,12 +617,6 @@ export default {
 
         .content {
           flex: 1;
-
-          :deep img {
-            max-width: 100%;
-            max-height: 42px;
-            object-fit: scale-down;
-          }
         }
       }
     }