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
相关产品推荐
相关产品推荐

