|
@@ -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;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|