WordPhrase.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. <template>
  2. <div
  3. class="NPC-zhedie"
  4. v-if="curQue"
  5. :class="[isPhone ? 'NPC-zhedie-phone' : '']"
  6. >
  7. <div :class="curQue.titleBg == 'white' ? 'topTitleWhite' : 'topTitle'">
  8. <div class="NPC-top-left">
  9. <template v-if="curQue.conDetail && curQue.conDetail.sentence">
  10. <div class="item-intro">
  11. <OneSentenceTemp
  12. :detail="curQue.conDetail"
  13. :TaskModel="TaskModel"
  14. :Bookanswer="[]"
  15. :correctAnswer="[]"
  16. :isInput="false"
  17. :fn_check_list="[]"
  18. :pyNumber="0"
  19. :record_check="[]"
  20. />
  21. </div>
  22. </template>
  23. <span class="NPC-topTitle-text" v-else>{{ curQue.title }}</span>
  24. <!-- <span
  25. :class="['NPC-play-all', playClass]"
  26. @click.stop="playNewwords"
  27. ></span> -->
  28. </div>
  29. <div class="NPC-top-right" @click="handleChangeTab">
  30. <span class="NPC-top-right-text">{{ wordShow ? "收起" : "展开" }}</span>
  31. <template v-if="curQue.titleBg == 'white'">
  32. <img
  33. v-if="wordShow"
  34. src="../../../assets/NPC/down-black.png"
  35. alt=""
  36. />
  37. <img v-else src="../../../assets/NPC/up-black.png" alt="" />
  38. </template>
  39. <template v-else>
  40. <img v-if="wordShow" src="../../../assets/NPC/down.png" alt="" />
  41. <img v-else src="../../../assets/NPC/up.png" alt="" />
  42. </template>
  43. </div>
  44. </div>
  45. <el-collapse-transition>
  46. <div
  47. class="NPC-word-list"
  48. v-if="curQue.option && curQue.option.length > 0"
  49. v-show="wordShow"
  50. >
  51. <div
  52. class="aduioLine-box"
  53. v-if="
  54. curQue.mp3_list &&
  55. curQue.mp3_list.length > 0 &&
  56. curQue.mp3_list[0].id
  57. "
  58. >
  59. <AudioLine
  60. :audioId="'SelectYinjieAudio' + indexStr"
  61. :mp3="curQue.mp3_list[0].id"
  62. :getCurTime="getCurTime"
  63. :themeColor="themeColor"
  64. :ed="ed"
  65. type="audioLine"
  66. ref="audioLine"
  67. @handleListenRead="handleListenRead"
  68. />
  69. </div>
  70. <ul class="NPC-word-table" cellspacing="0" border="0" cellpadding="0">
  71. <li
  72. class="NPC-word-tr"
  73. v-for="(item, index) in curQue.option"
  74. :key="'curQue.option' + index"
  75. >
  76. <div
  77. :class="[
  78. 'NPC-word-row',
  79. playClass && mp3_index == sItem.sIndex ? 'active' : '',
  80. curTime >= sItem.bg && curTime < sItem.ed && stopAudioS
  81. ? 'active'
  82. : ''
  83. ]"
  84. v-for="(sItem, sIndex) in item"
  85. :key="'curQue.option.child' + sIndex"
  86. >
  87. <template v-if="sItem.bg || sItem.ed">
  88. <a
  89. :class="[
  90. 'play-btn',
  91. curTime >= sItem.bg && curTime < sItem.ed && stopAudioS
  92. ? 'active'
  93. : ''
  94. ]"
  95. @click="handleChangeTime(sItem.bg, sItem.ed)"
  96. ></a>
  97. </template>
  98. <template
  99. v-else-if="
  100. sItem.mp3_list &&
  101. sItem.mp3_list.length > 0 &&
  102. sItem.mp3_list[0].id
  103. "
  104. >
  105. <span
  106. :class="[
  107. themeColor == 'green'
  108. ? 'NPC-play-btn-green'
  109. : themeColor == 'red'
  110. ? 'NPC-play-btn-red'
  111. : 'NPC-play-btn-brown',
  112. playClass && mp3_index == sItem.sIndex ? 'active' : ''
  113. ]"
  114. @click="palyAudio(sItem.sIndex)"
  115. ></span>
  116. <audio
  117. :id="'word' + indexStr + sItem.sIndex"
  118. :src="sItem.mp3_list[0].id"
  119. ></audio>
  120. </template>
  121. <template v-else>
  122. <span style="width: 16px; height: 16px"></span>
  123. </template>
  124. <div class="tabNum-box">
  125. <template v-if="sItem.mIndex == 0 || sItem.number">
  126. <b class="tabNum">{{
  127. sItem.number ? sItem.number : index + 1
  128. }}</b>
  129. </template>
  130. <div
  131. v-else
  132. style="width: 16px; height: 16px; margin-left: 8px"
  133. ></div>
  134. <img
  135. v-if="sItem.starFlag"
  136. class="star-label"
  137. :src="
  138. require('../../../assets/NPC/asterisk-' +
  139. themeColor +
  140. '.png')
  141. "
  142. />
  143. </div>
  144. <template
  145. v-if="
  146. sItem.pinyin_site &&
  147. (sItem.pinyin_site == 'top' ||
  148. sItem.pinyin_site == 'bottom')
  149. "
  150. >
  151. <div class="NPC-word-tab-box">
  152. <span
  153. class="NPC-word-tab-common NPC-word-tab-pinyin"
  154. :class="[
  155. sItem.motif_color
  156. ? 'NPC-word-tab-pinyin-' + themeColor
  157. : ''
  158. ]"
  159. v-if="sItem.pinyin_site == 'top'"
  160. >
  161. {{ sItem.pinyin }}
  162. </span>
  163. <span
  164. class="NPC-word-tab-common NPC-word-tab-word"
  165. :class="[
  166. sItem.motif_color
  167. ? 'NPC-word-tab-word-' + themeColor
  168. : '',
  169. curQue.whiteSpace ? 'NPC-word-tab-word-break' : ''
  170. ]"
  171. >
  172. {{ sItem.new_word }}
  173. </span>
  174. <span
  175. class="NPC-word-tab-common NPC-word-tab-pinyin"
  176. :class="[
  177. sItem.motif_color
  178. ? 'NPC-word-tab-pinyin-' + themeColor
  179. : ''
  180. ]"
  181. v-if="sItem.pinyin_site == 'bottom'"
  182. >
  183. {{ sItem.pinyin }}
  184. </span>
  185. </div>
  186. <span
  187. class="NPC-word-tab-common NPC-word-tab-cixing"
  188. :class="[
  189. /[\u4E00-\u9FA5\uF900-\uFA2D]/.test(sItem.cixing)
  190. ? 'hasCn'
  191. : '',
  192. sItem.motif_color ? 'NPC-word-tab-cixing-' + themeColor : ''
  193. ]"
  194. v-html="sItem.cixing"
  195. ></span>
  196. <span
  197. class="NPC-word-tab-common NPC-word-tab-def"
  198. :class="[
  199. sItem.motif_color ? 'NPC-word-tab-def-' + themeColor : ''
  200. ]"
  201. v-html="sItem.def_str"
  202. ></span>
  203. </template>
  204. <template v-else>
  205. <span
  206. class="NPC-word-tab-common NPC-word-tab-pinyin"
  207. :class="[
  208. sItem.motif_color ? 'NPC-word-tab-pinyin-' + themeColor : ''
  209. ]"
  210. v-if="!sItem.pinyin_site || sItem.pinyin_site == 'first'"
  211. >
  212. {{ sItem.pinyin }}
  213. </span>
  214. <span
  215. class="NPC-word-tab-common NPC-word-tab-word"
  216. :class="[
  217. sItem.motif_color ? 'NPC-word-tab-word-' + themeColor : '',
  218. curQue.whiteSpace ? 'NPC-word-tab-word-break' : ''
  219. ]"
  220. >
  221. {{ sItem.new_word }}
  222. </span>
  223. <span
  224. class="NPC-word-tab-common NPC-word-tab-pinyin"
  225. :class="[
  226. sItem.motif_color ? 'NPC-word-tab-pinyin-' + themeColor : ''
  227. ]"
  228. v-if="sItem.pinyin_site == 'last'"
  229. >
  230. {{ sItem.pinyin }}
  231. </span>
  232. <span
  233. class="NPC-word-tab-common NPC-word-tab-cixing"
  234. :class="[
  235. /[\u4E00-\u9FA5\uF900-\uFA2D]/.test(sItem.cixing)
  236. ? 'hasCn'
  237. : '',
  238. sItem.motif_color ? 'NPC-word-tab-cixing-' + themeColor : ''
  239. ]"
  240. v-html="sItem.cixing"
  241. ></span>
  242. <span
  243. class="NPC-word-tab-common NPC-word-tab-def"
  244. :class="[
  245. sItem.motif_color ? 'NPC-word-tab-def-' + themeColor : ''
  246. ]"
  247. v-html="sItem.def_str"
  248. ></span>
  249. </template>
  250. <span v-if="curQue.type == 'NewWord_chs'">
  251. <Soundrecord
  252. :tmIndex="index"
  253. :tmsIndex="sIndex"
  254. :TaskModel="TaskModel"
  255. @handleWav="handleWav"
  256. :modelType="curQue.type"
  257. :answerRecordList="
  258. judgeAnswer != 'standardAnswer'
  259. ? curQue.Bookanswer[index][sIndex].recordList
  260. : []
  261. "
  262. type="mini"
  263. class="luyin-box-wordphrase"
  264. :style="{ marginLeft: '8px' }"
  265. />
  266. </span>
  267. <span v-if="curQue.isInfor">
  268. <img
  269. src="../../../assets/NPC/detail-icon.png"
  270. class="detail-icon"
  271. @click="showDetail(sItem)"
  272. />
  273. </span>
  274. <div v-if="sItem.collocation" class="collocation">
  275. <span>搭配:</span><b v-html="sItem.collocation"></b>
  276. </div>
  277. <div
  278. v-if="
  279. sItem.liju_list &&
  280. sItem.liju_list.length > 0 &&
  281. sItem.liju_list[0]
  282. "
  283. class="collocation"
  284. >
  285. <span>例句:</span>
  286. <div>
  287. <b
  288. v-html="items"
  289. v-for="(items, indexs) in sItem.liju_list"
  290. :key="indexs"
  291. ></b>
  292. </div>
  293. </div>
  294. </div>
  295. </li>
  296. </ul>
  297. </div>
  298. </el-collapse-transition>
  299. <div class="practiceBox" v-if="detailShow">
  300. <WordPhraseDetail
  301. :data="data"
  302. :changeDetailIndex="changeDetailIndex"
  303. :closeWord="closeWordShow"
  304. :detailIndex="detailIndex"
  305. :optionRes="optionRes"
  306. :themeColor="themeColor"
  307. :currentTreeID="currentTreeID"
  308. :bg="data && data.bg ? data.bg : null"
  309. :ed="data && data.ed ? data.ed : null"
  310. type="newWordDetail"
  311. :isPhone="isPhone"
  312. />
  313. </div>
  314. <audio ref="newwordAudio" />
  315. </div>
  316. </template>
  317. <script>
  318. //这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  319. //例如:import 《组件名称》from ‘《组件路径》';
  320. import WordPhraseDetail from "./components/WordPhraseDetail.vue";
  321. import AudioLine from "../preview/AudioLine.vue";
  322. import Soundrecord from "../preview/Soundrecord.vue"; // 录音模板
  323. import OneSentenceTemp from "./components/OneSentenceTemp.vue";
  324. export default {
  325. //import引入的组件需要注入到对象中才能使用
  326. components: {
  327. WordPhraseDetail,
  328. AudioLine,
  329. Soundrecord,
  330. OneSentenceTemp
  331. },
  332. props: [
  333. "curQue",
  334. "themeColor",
  335. "currentTreeID",
  336. "indexs",
  337. "indexss",
  338. "indexStr",
  339. "TaskModel",
  340. "judgeAnswer",
  341. "isPhone"
  342. ],
  343. data() {
  344. //这里存放数据
  345. return {
  346. wordShow: this.curQue.hasOwnProperty("isWordShow")
  347. ? this.curQue.isWordShow
  348. : true,
  349. data: null,
  350. detailShow: false,
  351. detailIndex: 0,
  352. audio: new Audio(),
  353. playClass: "",
  354. mp3_index: -1,
  355. playWord: null,
  356. optionRes: [],
  357. mp3List: [],
  358. isSuccess: false,
  359. loading: false,
  360. mp3: "",
  361. curTime: 0,
  362. stopAudioS: false,
  363. ed: null,
  364. chsFhList: [",", "。", "“", ":", "》", "?", "!", ";"],
  365. titleChsFhList: [",", "”", "。", ":", "》", "?", "!", ";"]
  366. };
  367. },
  368. //计算属性 类似于data概念
  369. computed: {},
  370. //监控data中数据变化
  371. watch: {
  372. currentTreeID: {
  373. handler: function() {
  374. this.mp3_index = -1; // 全文预览
  375. this.optionRes = []; // 显示单词和短语
  376. this.mp3List = []; // 语音练习
  377. this.initData();
  378. },
  379. deep: true
  380. }
  381. },
  382. //方法集合
  383. methods: {
  384. handleChange(val) {},
  385. palyAudio(sIndex) {
  386. let _this = this;
  387. _this.stopAudio();
  388. let node = document.getElementById("word" + _this.indexStr + sIndex);
  389. let mp3 = node.src;
  390. let audio = document.getElementsByTagName("audio");
  391. if (
  392. audio &&
  393. audio.length > 0 &&
  394. window.location.href.indexOf("GCLS-Learn") == -1
  395. ) {
  396. audio.forEach(item => {
  397. if (item.src != mp3) {
  398. item.pause();
  399. }
  400. });
  401. }
  402. _this.playWord = node;
  403. if (node) {
  404. this.mp3_index = sIndex;
  405. node.play();
  406. }
  407. this.handleListenPlay(sIndex);
  408. },
  409. handleListenPlay(sIndex) {
  410. let _this = this;
  411. if (_this.playWord) {
  412. let _this = this;
  413. _this.playWord.addEventListener("play", function() {
  414. _this.playClass = "nn";
  415. });
  416. _this.playWord.addEventListener("pause", function() {
  417. _this.mp3_index = -1;
  418. _this.playClass = "";
  419. });
  420. _this.playWord.addEventListener("ended", function() {
  421. _this.mp3_index = -1;
  422. _this.playClass = "";
  423. });
  424. }
  425. },
  426. // 打开单词详情
  427. showDetail(item) {
  428. this.data = null;
  429. this.data = item;
  430. this.detailShow = true;
  431. this.detailIndex = item.sIndex;
  432. },
  433. // 关闭单词详情
  434. closeWordShow(val) {
  435. this.detailShow = val;
  436. },
  437. changeDetailIndex(val) {
  438. let _this = this;
  439. if (val == "last") {
  440. _this.detailIndex--;
  441. } else {
  442. _this.detailIndex++;
  443. }
  444. _this.data = null;
  445. _this.data = _this.optionRes[_this.detailIndex];
  446. //_this.getWordLiju(_this.data.new_word);
  447. },
  448. playNewwords() {
  449. let _this = this;
  450. if (_this.playWord) {
  451. _this.playWord.pause();
  452. }
  453. if (_this.playClass) {
  454. _this.$refs.newwordAudio.pause();
  455. // _this.mp3_index = -1;
  456. _this.playClass = "";
  457. } else {
  458. let mp3_index = _this.mp3_index == -1 ? 0 : _this.mp3_index;
  459. let leg = _this.mp3List.length;
  460. let mp3 = _this.mp3List[mp3_index].mp3_list[0].id;
  461. _this.mp3_index = _this.mp3List[mp3_index].sIndex;
  462. _this.handlePlayVoice(mp3);
  463. _this.$refs.newwordAudio.addEventListener("ended", function() {
  464. setTimeout(() => {
  465. if (_this.playClass != "nn") {
  466. if (mp3_index < leg - 1) {
  467. if (_this.playClass) {
  468. mp3_index = mp3_index + 1;
  469. _this.mp3_index = _this.mp3List[mp3_index].sIndex;
  470. mp3 =
  471. _this.mp3List[mp3_index].mp3_list.length > 0 &&
  472. _this.mp3List[mp3_index].mp3_list[0].id;
  473. if (mp3) {
  474. _this.handlePlayVoice(mp3);
  475. }
  476. }
  477. } else {
  478. _this.mp3_index = -1;
  479. _this.playClass = "";
  480. }
  481. }
  482. }, 1000);
  483. });
  484. }
  485. },
  486. handlePlayVoice3(mp3) {
  487. let _this = this;
  488. let audio = document.getElementsByTagName("audio");
  489. if (
  490. audio &&
  491. audio.length > 0 &&
  492. window.location.href.indexOf("GCLS-Learn") == -1
  493. ) {
  494. audio.forEach(item => {
  495. if (item.src != mp3) {
  496. item.pause();
  497. }
  498. });
  499. }
  500. if (!mp3) {
  501. return;
  502. }
  503. if (!_this.audio.paused) {
  504. _this.audio.pause();
  505. } else {
  506. _this.audio.pause();
  507. _this.audio.load();
  508. _this.audio.src = mp3;
  509. _this.audio.loop = false;
  510. _this.audio.play();
  511. }
  512. },
  513. handlePlayVoice(mp3) {
  514. let _this = this;
  515. let audio = document.getElementsByTagName("audio");
  516. if (
  517. audio &&
  518. audio.length > 0 &&
  519. window.location.href.indexOf("GCLS-Learn") == -1
  520. ) {
  521. audio.forEach(item => {
  522. if (item.src != mp3) {
  523. item.pause();
  524. }
  525. });
  526. }
  527. if (!mp3) {
  528. return;
  529. }
  530. // setTimeout(() => {
  531. //_this.$refs.newwordAudio.pause();
  532. _this.$refs.newwordAudio.src = mp3;
  533. //_this.$refs.newwordAudio.load();
  534. _this.$refs.newwordAudio.play();
  535. // }, 1000);
  536. },
  537. stopAudio() {
  538. this.$refs.newwordAudio.pause();
  539. },
  540. initData() {
  541. let _this = this;
  542. if (this.curQue.type == "NewWord_chs") {
  543. let resIndex = 0;
  544. let optionRes = [];
  545. let mp3List = [];
  546. let itemNumber = 0;
  547. let Bookanswer = [];
  548. this.curQue.option.forEach((item, index) => {
  549. optionRes = optionRes.concat(item);
  550. Bookanswer.push([]);
  551. item.forEach((sItem, sIndex) => {
  552. sItem.mIndex = sIndex;
  553. sItem.sIndex = resIndex;
  554. resIndex++;
  555. sItem.def_str =
  556. sItem.definition_list.length > 0
  557. ? sItem.definition_list.join("; ")
  558. : "";
  559. if (sItem.mp3_list[0]) {
  560. mp3List.push(sItem);
  561. }
  562. if (_this.curQue.wordTime && _this.curQue.wordTime[itemNumber]) {
  563. sItem.bg = _this.curQue.wordTime[itemNumber].bg;
  564. sItem.ed = _this.curQue.wordTime[itemNumber].ed;
  565. }
  566. itemNumber++;
  567. Bookanswer[index].push({
  568. recordList: []
  569. });
  570. });
  571. });
  572. this.optionRes = JSON.parse(JSON.stringify(optionRes));
  573. this.mp3List = mp3List;
  574. if (!this.curQue.Bookanswer) {
  575. this.$set(this.curQue, "Bookanswer", Bookanswer);
  576. }
  577. }
  578. if (this.curQue.hasOwnProperty("conDetail")) {
  579. if (this.curQue.conDetail.wordsList.length > 0) {
  580. this.curQue.conDetail.wordsList.forEach((sItem, sIndex) => {
  581. this.mergeWordSymbol(sItem);
  582. sItem.fontColor = "rgba(255, 255, 255, 1)";
  583. sItem.fontSize = "16px";
  584. sItem.fontWeight = "bold";
  585. });
  586. }
  587. this.$set(this.curQue.conDetail, "config", {
  588. fontColor: "#fff",
  589. fontFamily:
  590. "Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif, alabo",
  591. fontSize: "16px",
  592. fontWeight: "bold"
  593. });
  594. }
  595. },
  596. //词和标点合一起
  597. mergeWordSymbol(sItem) {
  598. if (this.titleChsFhList.indexOf(sItem.chs) > -1) {
  599. sItem.isShow = false;
  600. } else {
  601. sItem.isShow = true;
  602. }
  603. },
  604. handleChangeTab() {
  605. this.wordShow = !this.wordShow;
  606. },
  607. getCurTime(curTime) {
  608. this.curTime = curTime * 1000;
  609. },
  610. //点击播放某个句子
  611. handleChangeTime(time, edTime) {
  612. let _this = this;
  613. _this.curTime = time;
  614. _this.stopAudioS = true;
  615. _this.$refs.audioLine.onTimeupdateTime(time / 1000, true);
  616. _this.ed = edTime;
  617. },
  618. handleListenRead(playFlag) {
  619. this.stopAudioS = playFlag;
  620. },
  621. emptyEd() {
  622. this.ed = null;
  623. },
  624. handleWav(list, tmIndex, tmsIndex) {
  625. tmIndex = tmIndex ? tmIndex : 0;
  626. tmsIndex = tmsIndex ? tmsIndex : 0;
  627. this.$set(this.curQue.Bookanswer[tmIndex][tmsIndex], "recordList", list);
  628. }
  629. },
  630. //生命周期 - 创建完成(可以访问当前this实例)
  631. created() {
  632. this.initData();
  633. },
  634. //生命周期 - 挂载完成(可以访问DOM元素)
  635. mounted() {
  636. let _this = this;
  637. _this.$refs.newwordAudio.addEventListener("play", function() {
  638. _this.playClass = "active";
  639. });
  640. _this.$refs.newwordAudio.addEventListener("pause", function() {
  641. //_this.playClass = "";
  642. });
  643. },
  644. //生命周期-创建之前
  645. beforeCreated() {},
  646. //生命周期-挂载之前
  647. beforeMount() {},
  648. //生命周期-更新之前
  649. beforUpdate() {},
  650. //生命周期-更新之后
  651. updated() {},
  652. //生命周期-销毁之前
  653. beforeDestory() {},
  654. //生命周期-销毁完成
  655. destoryed() {},
  656. //如果页面有keep-alive缓存功能,这个函数会触发
  657. activated() {}
  658. };
  659. </script>
  660. <style lang="scss" scoped>
  661. /* @import url(); 引入css类 */
  662. .NPC-zhedie {
  663. width: 780px;
  664. margin-bottom: 24px;
  665. .aduioLine-box {
  666. margin-bottom: 8px;
  667. }
  668. .practiceBox {
  669. position: fixed;
  670. left: 0;
  671. top: 0;
  672. z-index: 999;
  673. width: 100%;
  674. height: 100vh;
  675. background: rgba(0, 0, 0, 0.19);
  676. box-sizing: border-box;
  677. overflow: hidden;
  678. overflow-y: auto;
  679. }
  680. .NPC-word-list {
  681. background: #f7f7f7;
  682. }
  683. .NPC-word-table {
  684. width: 100%;
  685. > .NPC-word-tr {
  686. background: #fff;
  687. border-radius: 8px;
  688. margin-bottom: 8px;
  689. .NPC-word-row {
  690. cursor: pointer;
  691. display: flex;
  692. flex-flow: wrap;
  693. justify-content: flex-start;
  694. padding: 8px 13px 8px 12px;
  695. border-radius: 8px;
  696. &.active {
  697. background: linear-gradient(
  698. 0deg,
  699. rgba(0, 0, 0, 0.08),
  700. rgba(0, 0, 0, 0.08)
  701. ),
  702. #ffffff;
  703. }
  704. > span {
  705. font-size: 16px;
  706. line-height: 150%;
  707. color: #000000;
  708. }
  709. }
  710. .tabNum-box {
  711. position: relative;
  712. .star-label {
  713. position: absolute;
  714. right: -6px;
  715. top: 1px;
  716. width: 6px;
  717. height: 6px;
  718. }
  719. }
  720. .tabNum {
  721. background: #de4444;
  722. text-align: center;
  723. width: 16px;
  724. height: 16px;
  725. color: #ffffff;
  726. border-radius: 50%;
  727. font-size: 12px;
  728. font-family: "robot", "alabo";
  729. line-height: 16px;
  730. margin-top: 4px;
  731. margin-left: 8px;
  732. display: block;
  733. }
  734. .NPC-word-tab-box {
  735. width: 240px;
  736. span {
  737. display: block;
  738. width: 100%;
  739. color: #000000;
  740. margin: 2px 0;
  741. }
  742. }
  743. .NPC-word-tab-common {
  744. padding-left: 8px;
  745. width: 125px;
  746. box-sizing: border-box;
  747. }
  748. .NPC-word-tab-pinyin {
  749. font-family: "GB-PINYINOK-B";
  750. // white-space: nowrap;
  751. font-size: 12px;
  752. word-break: break-word;
  753. &.NPC-word-tab-pinyin-red {
  754. color: #e35454;
  755. }
  756. &.NPC-word-tab-pinyin-green {
  757. color: #24b99e;
  758. }
  759. &.NPC-word-tab-pinyin-brown {
  760. color: #bd8865;
  761. }
  762. }
  763. .NPC-word-tab-word {
  764. font-family: "FZJCGFKTK";
  765. white-space: nowrap;
  766. font-size: 16px;
  767. &.NPC-word-tab-word-red {
  768. color: #e35454;
  769. }
  770. &.NPC-word-tab-word-green {
  771. color: #24b99e;
  772. }
  773. &.NPC-word-tab-word-brown {
  774. color: #bd8865;
  775. }
  776. &-break {
  777. white-space: normal;
  778. word-break: break-word;
  779. }
  780. }
  781. .NPC-word-tab-cixing {
  782. font-family: "robot", "alabo";
  783. // width: 48px;
  784. width: 60px;
  785. word-break: break-word;
  786. box-sizing: border-box;
  787. text-align: left;
  788. // font-style: italic; // 要求改为正体
  789. &.NPC-word-tab-cixing-red {
  790. color: #e35454;
  791. }
  792. &.NPC-word-tab-cixing-green {
  793. color: #24b99e;
  794. }
  795. &.NPC-word-tab-cixing-brown {
  796. color: #bd8865;
  797. }
  798. &.hasCn {
  799. font-size: 13px;
  800. }
  801. }
  802. .NPC-word-tab-def {
  803. flex: 1;
  804. font-family: "robot", "alabo";
  805. word-break: break-word;
  806. box-sizing: border-box;
  807. white-space: pre-wrap;
  808. &.NPC-word-tab-def-red {
  809. color: #e35454;
  810. }
  811. &.NPC-word-tab-def-green {
  812. color: #24b99e;
  813. }
  814. &.NPC-word-tab-def-brown {
  815. color: #bd8865;
  816. }
  817. }
  818. .collocation {
  819. width: 100%;
  820. display: flex;
  821. padding-top: 8px;
  822. > span {
  823. color: #000;
  824. font-size: 16px;
  825. font-weight: 400;
  826. line-height: 24px;
  827. flex-shrink: 0;
  828. }
  829. > div b {
  830. display: block;
  831. }
  832. > b,
  833. > div b {
  834. flex: 1;
  835. color: rgba(0, 0, 0, 0.65);
  836. font-size: 16px;
  837. font-weight: 400;
  838. line-height: 24px;
  839. font-family: "robot", "FZJCGFKTK", "alabo";
  840. }
  841. }
  842. }
  843. }
  844. .NPC-play-btn-brown {
  845. margin-top: 4px;
  846. width: 16px;
  847. height: 16px;
  848. display: block;
  849. background: url("../../../assets/NPC/play-brown.png") no-repeat left top;
  850. background-size: 100% 100%;
  851. &.active {
  852. background: url("../../../assets/NPC/icon-voice-play-brown.png") no-repeat
  853. left top;
  854. background-size: 100% 100%;
  855. }
  856. }
  857. .NPC-play-btn-green {
  858. margin-top: 4px;
  859. width: 16px;
  860. height: 16px;
  861. display: block;
  862. background: url("../../../assets/NPC/play-green.png") no-repeat left top;
  863. background-size: 100% 100%;
  864. &.active {
  865. background: url("../../../assets/NPC/icon-voice-play-green.png") no-repeat
  866. left top;
  867. background-size: 100% 100%;
  868. }
  869. }
  870. .NPC-play-btn-red {
  871. margin-top: 4px;
  872. width: 16px;
  873. height: 16px;
  874. display: block;
  875. background: url("../../../assets/NPC/play-red.png") no-repeat left top;
  876. background-size: 100% 100%;
  877. &.active {
  878. background: url("../../../assets/NPC/icon-voice-play-red.png") no-repeat
  879. left top;
  880. background-size: 100% 100%;
  881. }
  882. }
  883. .NPC-word-list {
  884. padding: 20px 24px;
  885. border: 1px solid rgba(0, 0, 0, 0.1);
  886. border-top: none;
  887. border-radius: 0 0 8px 8px;
  888. }
  889. .detail-icon {
  890. width: 24px;
  891. height: 24px;
  892. display: block;
  893. cursor: pointer;
  894. opacity: 0.5;
  895. }
  896. .play-btn {
  897. margin-top: 4px;
  898. width: 16px;
  899. height: 16px;
  900. background: url("../../../assets/NPC/play-red.png") center no-repeat;
  901. background-size: cover;
  902. &.active {
  903. background-image: url("../../../assets/NPC/icon-voice-play-red.png");
  904. background-size: cover;
  905. }
  906. }
  907. &-phone {
  908. width: 100%;
  909. }
  910. }
  911. .NPC-Big-Book-preview-green {
  912. .NPC-zhedie {
  913. .play-btn {
  914. background: url("../../../assets/NPC/play-green.png") center no-repeat;
  915. background-size: cover;
  916. &.active {
  917. background-image: url("../../../assets/NPC/icon-voice-play-green.png");
  918. background-size: cover;
  919. }
  920. }
  921. }
  922. }
  923. .NPC-Big-Book-preview-brown {
  924. .NPC-zhedie {
  925. .play-btn {
  926. background: url("../../../assets/NPC/play-brown.png") center no-repeat;
  927. background-size: cover;
  928. &.active {
  929. background-image: url("../../../assets/NPC/icon-voice-play-brown.png");
  930. background-size: cover;
  931. }
  932. }
  933. }
  934. }
  935. @keyframes firstrotate {
  936. 0% {
  937. transform: rotateZ(0deg);
  938. }
  939. 100% {
  940. transform: rotateZ(180deg);
  941. }
  942. }
  943. @keyframes huifuRotate {
  944. 0% {
  945. transform: rotateZ(180deg);
  946. }
  947. 100% {
  948. transform: rotateZ(0deg);
  949. }
  950. }
  951. .luyin-box-wordphrase {
  952. height: 24px;
  953. }
  954. </style>
  955. <style lang="scss">
  956. .NPC-zhedie {
  957. .topTitle {
  958. width: 100%;
  959. display: flex;
  960. justify-content: space-between;
  961. padding-left: 24px;
  962. padding-right: 16px;
  963. height: 48px;
  964. background: #e35454;
  965. border: 1px solid rgba(0, 0, 0, 0.1);
  966. overflow: hidden;
  967. border-radius: 8px 8px 0 0;
  968. .NPC-top-left {
  969. display: flex;
  970. justify-content: flex-start;
  971. align-items: center;
  972. .NPC-topTitle-text {
  973. font-family: "sourceR";
  974. font-size: 16px;
  975. color: #fff;
  976. font-weight: bold;
  977. margin-right: 8px;
  978. white-space: pre;
  979. }
  980. .NPC-play-all {
  981. width: 16px;
  982. height: 16px;
  983. background: url("../../../assets/NPC/play-white.png") no-repeat left top;
  984. background-size: 100% 100%;
  985. cursor: pointer;
  986. &.active {
  987. width: 16px;
  988. height: 16px;
  989. background: url("../../../assets/NPC/icon-voice-play-white.png")
  990. no-repeat left top;
  991. background-size: 100% 100%;
  992. }
  993. }
  994. }
  995. .NPC-top-right {
  996. display: flex;
  997. justify-content: flex-start;
  998. align-items: center;
  999. cursor: pointer;
  1000. &-text {
  1001. font-weight: normal;
  1002. font-size: 14px;
  1003. line-height: 16px;
  1004. color: #ffffff;
  1005. }
  1006. img {
  1007. width: 16px;
  1008. height: 16px;
  1009. margin-left: 4px;
  1010. }
  1011. }
  1012. img {
  1013. width: 24px;
  1014. height: 24px;
  1015. }
  1016. .rotate {
  1017. animation-name: firstrotate;
  1018. animation-direction: 2s;
  1019. animation-fill-mode: both;
  1020. animation-timing-function: linear;
  1021. }
  1022. }
  1023. .topTitleWhite {
  1024. width: 100%;
  1025. display: flex;
  1026. justify-content: space-between;
  1027. padding-left: 24px;
  1028. padding-right: 16px;
  1029. height: 48px;
  1030. background: #fff;
  1031. border: 1px solid rgba(0, 0, 0, 0.1);
  1032. overflow: hidden;
  1033. border-radius: 8px 8px 0 0;
  1034. .NPC-top-left {
  1035. display: flex;
  1036. justify-content: flex-start;
  1037. align-items: center;
  1038. .NPC-topTitle-text {
  1039. font-family: "sourceR";
  1040. font-size: 16px;
  1041. color: #000;
  1042. font-weight: bold;
  1043. margin-right: 8px;
  1044. }
  1045. .NPC-play-all {
  1046. width: 16px;
  1047. height: 16px;
  1048. background: url("../../../assets/NPC/play-red.png") no-repeat left top;
  1049. background-size: 100% 100%;
  1050. cursor: pointer;
  1051. &.active {
  1052. width: 16px;
  1053. height: 16px;
  1054. background: url("../../../assets/NPC/icon-voice-play-red.png")
  1055. no-repeat left top;
  1056. background-size: 100% 100%;
  1057. }
  1058. }
  1059. }
  1060. .NPC-top-right {
  1061. display: flex;
  1062. justify-content: flex-start;
  1063. align-items: center;
  1064. cursor: pointer;
  1065. &-text {
  1066. font-weight: normal;
  1067. font-size: 14px;
  1068. line-height: 16px;
  1069. color: #000;
  1070. }
  1071. img {
  1072. width: 16px;
  1073. height: 16px;
  1074. margin-left: 4px;
  1075. }
  1076. }
  1077. img {
  1078. width: 24px;
  1079. height: 24px;
  1080. }
  1081. .rotate {
  1082. animation-name: firstrotate;
  1083. animation-direction: 2s;
  1084. animation-fill-mode: both;
  1085. animation-timing-function: linear;
  1086. }
  1087. }
  1088. .el-collapse-item__content {
  1089. padding-bottom: 0;
  1090. }
  1091. .el-slider__button {
  1092. width: 8px;
  1093. height: 8px;
  1094. }
  1095. .el-slider__runway {
  1096. margin: 0;
  1097. padding: 0;
  1098. }
  1099. .el-slider {
  1100. position: relative;
  1101. // top: -3px;
  1102. }
  1103. .el-collapse {
  1104. background: #f7f7f7;
  1105. box-sizing: border-box;
  1106. border-radius: 8px;
  1107. }
  1108. .el-collapse-item__wrap {
  1109. border: 1px solid rgba(0, 0, 0, 0.1);
  1110. border-top: 0;
  1111. background: #f7f7f7;
  1112. border-radius: 0px 0px 8px 8px;
  1113. }
  1114. .el-collapse-item__arrow {
  1115. display: none;
  1116. }
  1117. .el-table__row {
  1118. padding: 4px 0;
  1119. }
  1120. }
  1121. .NPC-Big-Book-preview-green {
  1122. .NPC-zhedie {
  1123. .topTitle {
  1124. background: #24b99e !important;
  1125. }
  1126. .tabNum {
  1127. background: #24b99e !important;
  1128. }
  1129. .topTitleWhite {
  1130. .NPC-top-left {
  1131. .NPC-play-all {
  1132. background: url("../../../assets/NPC/play-green.png") no-repeat left
  1133. top;
  1134. background-size: 100% 100%;
  1135. &.active {
  1136. background: url("../../../assets/NPC/play-green.png") no-repeat left
  1137. top;
  1138. background-size: 100% 100%;
  1139. }
  1140. }
  1141. }
  1142. }
  1143. }
  1144. }
  1145. .NPC-Big-Book-preview-brown {
  1146. .NPC-zhedie {
  1147. .topTitle {
  1148. background: #bd8865 !important;
  1149. }
  1150. .tabNum {
  1151. background: #bd8865 !important;
  1152. }
  1153. .topTitleWhite {
  1154. .NPC-top-left {
  1155. .NPC-play-all {
  1156. background: url("../../../assets/NPC/play-brown.png") no-repeat left
  1157. top;
  1158. background-size: 100% 100%;
  1159. &.active {
  1160. background: url("../../../assets/NPC/play-brown.png") no-repeat left
  1161. top;
  1162. background-size: 100% 100%;
  1163. }
  1164. }
  1165. }
  1166. }
  1167. }
  1168. }
  1169. </style>