浏览代码

试题音频 inline

Michael Wang 5 年之前
父节点
当前提交
bbe189cb6c

+ 1 - 1
src/features/OnlineExam/Examing/BooleanQuestionView.vue

@@ -157,7 +157,7 @@ export default {
 
 .question-body {
   font-size: 18px;
-  margin-bottom: 10px;
+  /* margin-bottom: 10px; */
 }
 
 .ops {

+ 1 - 0
src/features/OnlineExam/Examing/ExamingHome.vue

@@ -346,6 +346,7 @@ export default {
       snapNow: false,
       snapProcessingCount: 0,
     });
+    // TODO: 是否是个错误点?this.$Modal 不存在?
     this.$Modal.remove();
     // 避免macos上下塘动。避免产生滚动条。
     document.body.classList.toggle("hide-body-scroll", false);

+ 1 - 1
src/features/OnlineExam/Examing/FillBlankQuestionView.vue

@@ -197,7 +197,7 @@ export default {
 
 .question-body {
   font-size: 18px;
-  margin-bottom: 10px;
+  /* margin-bottom: 10px; */
 }
 
 .ops {

+ 1 - 1
src/features/OnlineExam/Examing/MultipleQuestionView.vue

@@ -219,7 +219,7 @@ export default {
 
 .question-body {
   font-size: 18px;
-  margin-bottom: 10px;
+  /* margin-bottom: 10px; */
 }
 
 .ops {

+ 1 - 1
src/features/OnlineExam/Examing/QuestionAudio.vue

@@ -1,5 +1,5 @@
 <template>
-  <span style="display: flex; align-items: center; ">
+  <span style="display: inline-flex; align-items: center; ">
     <span v-show="shouldShowAudio" @click="play">
       <Button
         v-if="!playing"

+ 41 - 27
src/features/OnlineExam/Examing/QuestionBody.vue

@@ -4,12 +4,16 @@
     :key="examQuestion.questionId"
     class="question-body"
   >
-    <div v-html="questionDetail.text"></div>
+    <QuestionContainer
+      :node="questionDetail.container"
+      :exam-question="examQuestion"
+    />
+    <!-- <div v-html="questionDetail.text"></div> -->
     <!-- <div v-html="questionDetail.audio"></div> -->
-    <div
+    <!-- <div
       v-for="{ src, name } in questionDetail.audio"
       :key="name"
-      class="audio-div"
+      class="audio-container"
     >
       <div style="position: relative; margin-bottom: 2px;" class="audio-div">
         <QuestionAudio
@@ -29,21 +33,23 @@
           style="position: absolute;top: 0;right: 0;bottom: 0;left: 0;"
         ></div>
       </div>
-    </div>
+    </div> -->
   </div>
 
   <div v-else>获取试题中...</div>
 </template>
 
 <script>
-import QuestionAudio from "./QuestionAudio";
+// import QuestionAudio from "./QuestionAudio";
+import QuestionContainer from "./QuestionContainer";
 import { createNamespacedHelpers } from "vuex";
 const { mapState, mapMutations } = createNamespacedHelpers("examingHomeModule");
 
 export default {
   name: "QuestionBody",
   components: {
-    QuestionAudio,
+    // QuestionAudio,
+    QuestionContainer,
   },
   props: {
     questionBody: { type: String, default: "" },
@@ -74,18 +80,24 @@ export default {
   },
   mounted() {
     this.parseQuestion();
+    // this.$nextTick(() => {
+    //   const ap = document.querySelectorAll(".audio-placeholder");
+    //   const as = document.querySelectorAll(".audio-container");
+    //   [...ap].forEach((v, i) => (v.innerHTML = [...as][i].innerHTML));
+    // });
   },
   methods: {
     ...mapMutations(["updateExamQuestion", "updateQuestionAudioPlayTimes"]),
     async parseQuestion() {
       let question = {};
+      const container = document.createElement("div");
       if (this.questionBody.includes("question-audio")) {
         question.text = this.questionBody.replace(
-          /<a.*?question-audio.*?\/a>/g,
-          ""
+          /<a.*?name="([^"]*)".*?question-audio.*?url="([^"]*)".*?\/a>/g,
+          "<span class='audio-placeholder' data-name='$1' data-src='$2'></span>"
         );
+        // console.log(question.text);
         // 测试 v-html中含有directive是否生效。结论:不生效
-
         question.audio = [];
         let re;
         if (/<a.*?question-audio.*?\/a>/.test(this.questionBody)) {
@@ -99,33 +111,35 @@ export default {
         question.text = this.questionBody;
         question.audio = [];
       }
+      container.innerHTML = question.text;
+      question.container = container;
       this.questionDetail = question;
     },
-    played(name) {
-      if (!this.examQuestion.limitedPlayTimes) {
-        // 如果没有设置音频播放次数,可无限播放
-        return false;
-      }
-      console.log("开始播放");
+    // played(name) {
+    //   if (!this.examQuestion.limitedPlayTimes) {
+    //     // 如果没有设置音频播放次数,可无限播放
+    //     return false;
+    //   }
+    //   console.log("开始播放");
 
-      // 正在播放中
-      this.updateQuestionAudioPlayTimes(name);
-    },
-    getAudioPlayedTimes(name) {
-      return Math.max(
-        this.examQuestion.limitedPlayTimes -
-          (this.allAudioPlayTimes.find(a => a.name === name) || { times: 0 })
-            .times,
-        0
-      );
-    },
+    //   // 正在播放中
+    //   this.updateQuestionAudioPlayTimes(name);
+    // },
+    // getAudioPlayedTimes(name) {
+    //   return Math.max(
+    //     this.examQuestion.limitedPlayTimes -
+    //       (this.allAudioPlayTimes.find(a => a.name === name) || { times: 0 })
+    //         .times,
+    //     0
+    //   );
+    // },
   },
 };
 </script>
 
 <style>
 .audio-div {
-  display: flex;
+  display: inline-flex;
   align-items: center;
 }
 /* .question-body audio::-webkit-media-controls-timeline,

+ 98 - 0
src/features/OnlineExam/Examing/QuestionContainer.vue

@@ -0,0 +1,98 @@
+<template>
+  <div>
+    <template v-for="(item, index) in node.childNodes">
+      <template v-if="item.className === 'audio-placeholder'">
+        <div
+          :key="index"
+          style="position: relative; margin-bottom: 2px;"
+          class="audio-div"
+        >
+          <QuestionAudio
+            :name="item.getAttribute('data-name')"
+            :src="item.getAttribute('data-src')"
+            :play-count="
+              examQuestion.limitedPlayTimes
+                ? getAudioPlayedTimes(item.getAttribute('data-name'))
+                : 1
+            "
+            @played="played(item.getAttribute('data-name'))"
+          />
+          <span v-if="examQuestion.limitedPlayTimes">
+            (剩余播放次数:{{
+              getAudioPlayedTimes(item.getAttribute("data-name"))
+            }})
+          </span>
+          <div
+            v-if="audioInPlay.has(item.getAttribute('data-name'))"
+            style="position: absolute;top: 0;right: 0;bottom: 0;left: 0;"
+          ></div>
+        </div>
+      </template>
+      <!-- <template v-else-if="item.nodeType == 3" v-text="item.nodeValue" /> -->
+      <template v-else-if="item.nodeType == 3">
+        {{ item.nodeValue }}
+      </template>
+      <template
+        v-else-if="
+          item.childNodes &&
+            item.querySelector &&
+            item.querySelector('.audio-placeholder')
+        "
+      >
+        <QuestionContainer
+          :key="index"
+          :node="item"
+          :exam-question="examQuestion"
+          :audio-in-play="audioInPlay"
+        />
+      </template>
+
+      <!-- <template v-else v-html="item.outerHTML"></template> -->
+      <span v-else :key="index" v-html="item.outerHTML"></span>
+      <!-- <p v-else v-html="item.outerHTML"></p> -->
+      <!-- <template v-else>{{ item.outerHTML }}</template> -->
+    </template>
+  </div>
+</template>
+
+<script>
+import QuestionAudio from "./QuestionAudio";
+import { createNamespacedHelpers } from "vuex";
+const { mapState, mapMutations } = createNamespacedHelpers("examingHomeModule");
+
+export default {
+  name: "QuestionContainer",
+  components: {
+    QuestionAudio,
+  },
+  props: {
+    node: { type: HTMLElement, default: () => {} },
+    examQuestion: { type: Object, default: () => {} },
+    audioInPlay: { type: Set, default: () => new Set() },
+  },
+  computed: {
+    ...mapState(["allAudioPlayTimes"]),
+  },
+  methods: {
+    ...mapMutations(["updateExamQuestion", "updateQuestionAudioPlayTimes"]),
+    played(name) {
+      if (!this.examQuestion.limitedPlayTimes) {
+        // 如果没有设置音频播放次数,可无限播放
+        return false;
+      }
+      console.log("开始播放");
+
+      // 正在播放中
+      this.updateQuestionAudioPlayTimes(name);
+    },
+    getAudioPlayedTimes(name) {
+      return Math.max(
+        this.examQuestion.limitedPlayTimes -
+          (this.allAudioPlayTimes.find(a => a.name === name) || { times: 0 })
+            .times,
+        0
+      );
+    },
+  },
+};
+</script>

+ 1 - 1
src/features/OnlineExam/Examing/SingleQuestionView.vue

@@ -201,7 +201,7 @@ export default {
 
 .question-body {
   font-size: 18px;
-  margin-bottom: 10px;
+  /* margin-bottom: 10px; */
 }
 
 .ops {

+ 1 - 1
src/features/OnlineExam/Examing/TextQuestionView.vue

@@ -434,7 +434,7 @@ export default {
 
 .question-body {
   font-size: 18px;
-  margin-bottom: 10px;
+  /* margin-bottom: 10px; */
 }
 
 .ops {