You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS开发多选答题游戏 首题后得分每次累加2分而非1分问题排查

问题根本原因

计分翻倍是重复绑定点击事件监听器导致的:

  • 每次调用iterarJuego()渲染新题目时,都会执行内部的elegirRespuesta()方法
  • elegirRespuesta()的作用是给4个选项按钮绑定click事件,但DOM元素的事件监听器不会因为重复绑定被覆盖,新绑定的监听器会追加到执行队列里
  • 答第一题时每个选项仅绑定了1个监听器,点击后计分逻辑只执行1次,数值正常;答第二题时每个选项已经累计绑定了2个监听器,点击1次会触发2次计分逻辑,分数、答题数就会变成预期值的2倍,后续题目绑定的监听器会持续累加,数值偏差会越来越大。
修复方法

两种实现都可以解决问题,优先选第一种更简洁。

方法一:初始化时仅绑定一次事件(推荐)

事件绑定不需要跟着题目渲染重复执行,只需要页面首次加载时绑定一次即可:

  1. 删除iterarJuego()函数中调用elegirRespuesta()的代码行
  2. 修改页面最末尾的初始化逻辑,先绑定事件再渲染第一题:
// 页面初始化
elegirRespuesta(); // 仅在页面加载时绑定一次点击事件
iterarJuego(); // 渲染第一道题目

方法二:每次绑定事件前清除旧监听器

如果要保留每次切题重新绑定事件的结构,在绑定新事件前清除之前绑定的监听器即可,修改elegirRespuesta代码如下:

// 抽离公共点击处理逻辑
function onOptionSelect(respuesta) {
  respSeleccionada = respuesta;
  funAnalizar(respSeleccionada);
}

function elegirRespuesta() {
  // 通过克隆节点的方式清除节点上所有已绑定的事件
  [opcion1, opcion2, opcion3, opcion4].forEach((opcion, index) => {
    const nuevoNodo = opcion.cloneNode(true);
    opcion.replaceWith(nuevoNodo);
    // 更新节点引用
    window[`opcion${index+1}`] = nuevoNodo;
  });

  // 绑定新的点击事件
  opcion1.addEventListener("click", () => onOptionSelect(arrayPreguntas[idPreg].opcionuno));
  opcion2.addEventListener("click", () => onOptionSelect(arrayPreguntas[idPreg].opciondos));
  opcion3.addEventListener("click", () => onOptionSelect(arrayPreguntas[idPreg].opciontres));
  opcion4.addEventListener("click", () => onOptionSelect(arrayPreguntas[idPreg].opcioncuatro));
}
其他可优化的代码问题
  • document.querySelector('puntito1')选择器写法错误:如果是匹配class需要加前缀.,即document.querySelector('.puntito1');如果是匹配id需要加前缀#
  • funAnalizar、respCorrecta、respIncorrecta三个函数定义了形参但函数内部没有使用,属于冗余代码,可以删除形参定义
  • iterarJuego函数声明时没有定义入参,调用时传入idPreg属于无效传参,可以删掉调用时传入的参数
  • opcion4.innerText = arrayPreguntas[idPreg].opcioncuatro;;行尾多写了一个分号,不影响运行但可以清理

内容的提问来源于stack exchange,提问作者Valentín Sanabria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:55:05