如何在单篇博客中复用相同JavaScript代码实现多道问答题目?
实现方案
核心优化思路
把每道问答题目封装为独立的DOM单元,去掉硬编码的id和每个选项绑定的独立函数,通过自定义属性和DOM层级查找实现通用逻辑,新增题目时只需要写HTML结构,不需要修改JS代码,完全不会出现跨题冲突。
完整优化后的代码
首先提前写好全局通用样式,避免重复编写内联样式:
.qa-item { background: white; margin: 20px 0; } .qa-option { background: white; font-size: 20px; padding: 10px; border: 2px solid black; margin: 8px 0; cursor: pointer; } .qa-explanation { background: white; display: none; margin-top: 15px; padding: 10px; border-left: 3px solid #ccc; } .correct { background-color: PaleGreen !important; } .wrong { background-color: #FAA0A0 !important; }
然后是HTML部分,所有题目都放在qa-container容器里:
<h2>Questions</h2> <div class="qa-container"> <!-- 第1道题 --> <div class="qa-item"> <p>1. If we increase the frequency of oscillation, the velocity of the wave... </p> <div class="qa-option"> <input name="q1-option" type="radio" value="wrong"> Increases </div> <div class="qa-option"> <input name="q1-option" type="radio" value="wrong"> Decreases </div> <!-- 正确选项加data-correct="true"标记 --> <div class="qa-option"> <input name="q1-option" type="radio" value="correct" data-correct="true"> Does not change </div> <div class="qa-explanation"> <span class="correct-tip"></span><br> $v=f\lambda$ does not mean that velocity is directly proportional to frequency.<br> When we increase frequency($f$), waves are closer-hence the wavelength($\lambda$) decreases keeping the velocity unchanged ($v=f\lambda$).<br> Velocity only depends upon the material property of the medium of propagation.<br> For example sound waves in water moves faster than in air because water has higher density. <br>But the speed of sound waves does not change if we speak in higher frequency. </div> </div> <!-- 第2道题 直接复制结构修改内容即可 --> <div class="qa-item"> <p>2. 以下哪种介质中声音传播速度最快?</p> <div class="qa-option"> <input name="q2-option" type="radio" value="wrong"> 空气 </div> <!-- 正确选项加标记 --> <div class="qa-option"> <input name="q2-option" type="radio" value="correct" data-correct="true"> 钢铁 </div> <div class="qa-option"> <input name="q2-option" type="radio" value="wrong"> 纯水 </div> <div class="qa-explanation"> <span class="correct-tip"></span><br> 声音的传播速度和介质密度正相关,钢铁密度远大于水和空气,因此声音在钢铁中的传播速度最快,可达5200m/s。 </div> </div> <!-- 后续新增题目直接复制上面qa-item的结构修改内容即可 --> </div>
最后是通用JS代码,只需要写一次,不需要随题目新增修改:
// 事件委托绑定在父容器上,所有选项点击都会触发 document.querySelector('.qa-container').addEventListener('click', function(e) { // 只处理单选框的点击事件 if (e.target.tagName !== 'INPUT' || e.target.type !== 'radio') return; // 找到当前题目所属的独立单元 const currentQa = e.target.closest('.qa-item'); // 找到当前点击的选项容器 const currentOption = e.target.closest('.qa-option'); // 找到当前题目的解析模块和正确提示节点 const exp = currentQa.querySelector('.qa-explanation'); const tip = exp.querySelector('.correct-tip'); // 先清空当前题所有选项的样式 currentQa.querySelectorAll('.qa-option').forEach(opt => { opt.classList.remove('correct', 'wrong'); }); // 判断是否选对 const isCorrect = e.target.hasAttribute('data-correct'); if (isCorrect) { currentOption.classList.add('correct'); tip.textContent = 'Correct!'; } else { currentOption.classList.add('wrong'); tip.textContent = 'Wrong!'; // 把正确选项标绿 currentQa.querySelector('input[data-correct="true"]').closest('.qa-option').classList.add('correct'); } // 展示解析 exp.style.display = 'block'; });
新增题目操作方法
后续需要加题时,只需要复制qa-item的整段结构,修改四个地方即可:
- 题目内容和选项内容
- 单选框的name属性,改成和其他题目不一样的即可,比如第3题就改成
q3-option - 给正确的选项对应的input加上
data-correct="true"属性 - 修改解析内容
不需要修改任何JS代码,也不会出现跨题冲突的问题。
内容的提问来源于stack exchange,提问作者Sophile
相关产品推荐
相关产品推荐

