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

getAttribute返回值异常:Django闪卡应用点击事件获取data属性错误

解决循环绑定点击事件时始终获取最后一个元素data属性的问题

问题原因

你碰到的是JS闭包作用域的经典坑:循环里的question变量没有用块级作用域声明,循环结束后它会指向最后一个<h2>元素,所有点击事件触发时都会引用这个最终的变量值,所以不管点哪个都输出最后一个ID。

解决方案

这里提供几种靠谱的解决方式,按推荐程度排序:

1. 用事件对象/this获取当前点击元素(最推荐)

不需要依赖循环里的外部变量,直接从点击事件本身拿到触发元素,还能顺便实现闪卡的核心功能:

const questions = document.querySelectorAll('h2[data-question-obj-id]');

questions.forEach(question => {
  question.addEventListener('click', function() {
    // 用dataset属性直接获取(自动转换为驼峰命名)
    const questionId = this.dataset.questionObjId;
    console.log(questionId);
    
    // 切换对应答案的显示/隐藏状态
    const answer = document.querySelector(`p[data-question-obj-id="${questionId}"]`);
    answer.style.display = answer.style.display === 'none' ? 'block' : 'none';
  });
});

2. 给循环变量添加块级作用域

在循环内部用let声明question,让每次循环都创建独立的变量绑定:

const questions = document.querySelectorAll('h2[data-question-obj-id]');

for (let i = 0; i < questions.length; i++) {
  let question = questions[i]; // 关键:用let声明变量
  question.addEventListener('click', function() {
    console.log(question.getAttribute("data-question-obj-id"));
  });
}

3. 使用IIFE(立即执行函数)包裹

这是ES6之前常用的解决方案,现在用上面两种更简洁:

const questions = document.querySelectorAll('h2[data-question-obj-id]');

for (let i = 0; i < questions.length; i++) {
  (function(question) {
    question.addEventListener('click', function() {
      console.log(question.getAttribute("data-question-obj-id"));
    });
  })(questions[i]);
}

补充:初始隐藏答案的CSS

要实现闪卡初始隐藏答案的效果,先添加一段基础样式:

p[data-question-obj-id] {
  display: none;
}

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:28:17