小草驾考宝典_H5/app.js · 约 3853 字符
1// 小草驾考宝典 · 逻辑层
2const $=s=>document.querySelector(s), $$=s=>document.querySelectorAll(s);
3const store={
4 get exams(){return JSON.parse(localStorage.getItem('dr_exams')||'[]')},
5 set exams(v){localStorage.setItem('dr_exams',JSON.stringify(v))},
6 get wrong(){return JSON.parse(localStorage.getItem('dr_wrong')||'[]')},
7 set wrong(v){localStorage.setItem('dr_wrong',JSON.stringify(v))}
8};
9function toast(msg){const t=document.createElement('div');t.textContent=msg;t.style.cssText='position:fixed;top:20%;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.78);color:#fff;padding:10px 20px;border-radius:20px;font-size:13px;z-index:999;transition:opacity .3s';document.body.appendChild(t);setTimeout(()=>{t.style.opacity='0';setTimeout(()=>t.remove(),300)},1200)}
10/* 答题器 */
11let Q={idx:0,list:[],score:0,answered:false};
12function renderQ(){
13 const q=Q.list[Q.idx];if(!q)return;
14 $('#q-no').textContent='第 '+(Q.idx+1)+' / '+Q.list.length+' 题';
15 $('#q-text').textContent=q.q;
16 const opts=[['A',q.a],['B',q.b],['C',q.c],['D',q.d]];
17 $('#q-opts').innerHTML=opts.map(([k,v])=>'<div class="option" data-k="'+k+'"><span class="op-key">'+k+'</span><span style="flex:1">'+v+'</span></div>').join('');
18 $$('.option').forEach(o=>o.onclick=()=>choose(o.dataset.k));
19 $('#q-answer').classList.remove('show');$('#q-explain').classList.remove('show');
20 $('#q-answer').innerHTML='';$('#q-explain').innerHTML='';
21 Q.answered=false;
22}
23function choose(k){
24 if(Q.answered)return;Q.answered=true;
25 const q=Q.list[Q.idx];
26 const opts=$$('.option');
27 opts.forEach(o=>{
28 if(o.dataset.k===q.ans){o.classList.add('correct');o.insertAdjacentHTML('beforeend','<span class="op-right">✅</span>')}
29 else if(o.dataset.k===k){o.classList.add('wrong');o.insertAdjacentHTML('beforeend','<span class="op-right">❌</span>')}
30 });
31 const correct=k===q.ans;
32 if(correct)Q.score++;else{store.wrong=store.wrong.includes(q.q)?store.wrong:[...store.wrong,q.q]}
33 $('#q-answer').innerHTML='<b style="color:var(--green)">正确答案:'+q.ans+'</b>';
34 $('#q-answer').classList.add('show');
35 $('#q-explain').textContent='💡 '+q.explain;
36 $('#q-explain').classList.add('show');
37}
38function nextQ(){
39 if(Q.idx<Q.list.length-1){Q.idx++;renderQ()}
40 else{finishQuiz()}
41}
42function finishQuiz(){
43 const q=Q.list[0];const examMode=Q.list.length>10;
44 const score=examMode?Math.round(Q.score/Q.list.length*100):Q.score;
45 if(examMode){
46 const record={score,time:new Date().toLocaleString('zh-CN',{month:'numeric',day:'numeric',hour:'2-digit',minute:'2-digit'}),total:Q.list.length,right:Q.score,pass:score>=90};
47 store.exams=[record,...store.exams];
48 }
49 localStorage.setItem('dr_lastq',JSON.stringify({score,total:Q.list.length}));
50 toast(examMode?'交卷成功!得分 '+score+' 分':'本组练习完成,答对 '+score+' 题');
51 setTimeout(()=>location.href=examMode?'mine.html':'practice.html',900);
52}
53function renderMine(){
54 $('#u-name').textContent=USER.name;$('#u-stage').textContent='当前阶段:'+USER.stage;
55 $('#m-progress').textContent=USER.progress+'%';$('#m-wrong').textContent=store.wrong.length||USER.wrong;
56 $('#m-exams').textContent=store.exams.length||USER.exams;
57 const best=store.exams.length?Math.max(...store.exams.map(e=>e.score)):USER.score;
58 $('#m-best').textContent=best;
59 const list=store.exams;
60 $('#exam-records').innerHTML=list.length?list.slice(0,5).map(e=>'<div style="display:flex;justify-content:space-between;font-size:13px;padding:8px 0;border-bottom:1px dashed #eef2f9"><span>'+e.time+' · '+e.right+'/'+e.total+'题</span><b style="color:'+(e.pass?'var(--green)':'var(--red)')+'">'+e.score+'分 '+(e.pass?'✅':'❌')+'</b></div>').join(''):'<div class="empty">暂无考试记录<br>去模拟考试试试手</div>';
61}
62