如何将三个近乎相同的JavaScript函数优化为一个?
优化重复的JavaScript代码方案
原始重复代码
let quizCheck1Option = document.querySelectorAll('.js-quiz_step2check1_option-popup'); let quizCheck1Img = document.querySelectorAll('.js-quiz_step2check1_img'); let quizCheck1Title = document.querySelectorAll('.js-quiz_step2check1_title'); quizCheck1Option.forEach(label => { label.addEventListener('click', function() { quizCheck1Img.forEach(img => { img.setAttribute("src", label.dataset.src); document.getElementById('quiz2-option-1').checked = true; }) quizCheck1Title.forEach(title => { title.innerText = label.dataset.name; }) }) }) let quizCheck2Option = document.querySelectorAll('.js-quiz_step2check2_option-popup'); let quizCheck2Img = document.querySelectorAll('.js-quiz_step2check2_img'); let quizCheck2Title = document.querySelectorAll('.js-quiz_step2check2_title'); quizCheck2Option.forEach(label => { label.addEventListener('click', function() { quizCheck2Img.forEach(img => { img.setAttribute("src", label.dataset.src); document.getElementById('quiz2-option-2').checked = true; }) quizCheck2Title.forEach(title => { title.innerText = label.dataset.name; }) }) }) let quizCheck3Option = document.querySelectorAll('.js-quiz_step2check3_option-popup'); let quizCheck3Img = document.querySelectorAll('.js-quiz_step2check3_img'); let quizCheck3Title = document.querySelectorAll('.js-quiz_step2check3_title'); quizCheck3Option.forEach(label => { label.addEventListener('click', function() { quizCheck3Img.forEach(img => { img.setAttribute("src", label.dataset.src); document.getElementById('quiz2-option-3').checked = true; }) quizCheck3Title.forEach(title => { title.innerText = label.dataset.name; }) }) })
核心优化方案:循环复用代码
通过遍历数字标识,把重复逻辑抽离,只用一段代码就能处理所有3组元素:
// 遍历1到3的数字,批量处理每一组元素 for (let i = 1; i <= 3; i++) { // 动态生成选择器,替换数字部分 const options = document.querySelectorAll(`.js-quiz_step2check${i}_option-popup`); const imgs = document.querySelectorAll(`.js-quiz_step2check${i}_img`); const titles = document.querySelectorAll(`.js-quiz_step2check${i}_title`); const checkboxId = `quiz2-option-${i}`; options.forEach(label => { label.addEventListener('click', () => { // 简化DOM属性赋值:直接用.src代替setAttribute imgs.forEach(img => img.src = label.dataset.src); // 勾选对应复选框 document.getElementById(checkboxId).checked = true; // 更新标题文本 titles.forEach(title => title.innerText = label.dataset.name); }); }); }
新手友好的额外优化建议
- 用const代替let:如果变量不需要重新赋值,使用
const能让代码更严谨,避免意外修改。 - 事件委托(进阶优化):如果后续会动态新增选项,给父元素绑定一次事件即可,不用重复给新元素绑定:
// 假设所有选项的父容器有统一类名.js-quiz_step2_options-container document.querySelector('.js-quiz_step2_options-container').addEventListener('click', (e) => { // 找到点击的目标选项标签 const label = e.target.closest('.js-quiz_step2check_option-popup'); if (!label) return; // 从类名中提取数字标识 const match = label.className.match(/js-quiz_step2check(\d+)_option-popup/); if (!match) return; const i = match[1]; const imgs = document.querySelectorAll(`.js-quiz_step2check${i}_img`); const titles = document.querySelectorAll(`.js-quiz_step2check${i}_title`); const checkboxId = `quiz2-option-${i}`; imgs.forEach(img => img.src = label.dataset.src); document.getElementById(checkboxId).checked = true; titles.forEach(title => title.innerText = label.dataset.name); }); - 缓存DOM元素:如果这些元素不会动态变化,可以在页面加载时一次性查询并缓存,避免重复遍历DOM,提升性能。
内容的提问来源于stack exchange,提问作者display.name
相关产品推荐
相关产品推荐

