为何仅首个contentDivs元素触发mouseenter背景变色效果?
问题原因与解决方案
问题根源
- HTML里的
id是唯一标识,你循环创建64个div时都设置了同一个idcontentDivs,这本身就违反了HTML规范 document.getElementById('contentDivs')只会返回页面中第一个匹配该ID的元素,所以事件监听器只绑定到了第一个div上;触发事件时,也只会修改第一个div的背景色,其余div根本没被处理
解决方案
方案1:创建元素时直接绑定事件
这种方式直观,每个div创建时就绑定专属的事件监听器:
for(let x=0; x<64; x++) { const contentDiv = document.createElement('div'); contentDiv.classList.add('contentDiv'); // 用class代替重复id contentDiv.addEventListener('mouseenter', function() { this.style.background = 'black'; // this指向当前触发事件的div }); document.getElementById('mainContainer').appendChild(contentDiv); }
方案2:事件委托(推荐,更高效)
不用给每个div单独绑事件,利用事件冒泡特性,给父容器绑定一次事件即可:
// 先批量创建div for(let x=0; x<64; x++) { const contentDiv = document.createElement('div'); contentDiv.classList.add('contentDiv'); document.getElementById('mainContainer').appendChild(contentDiv); } // 给父容器绑定事件,统一处理子元素的mouseenter事件 document.getElementById('mainContainer').addEventListener('mouseenter', function(e) { // 确认触发事件的是目标div if(e.target.classList.contains('contentDiv')) { e.target.style.background = 'black'; } });
这种方式内存占用更低,后续新增div也无需重新绑定事件。
方案3:批量选择元素绑定事件(不推荐大量元素使用)
通过class选择器获取所有div,循环绑定事件:
for(let x=0; x<64; x++) { const contentDiv = document.createElement('div'); contentDiv.classList.add('contentDiv'); document.getElementById('mainContainer').appendChild(contentDiv); } // 遍历所有目标div绑定事件 document.querySelectorAll('.contentDiv').forEach(div => { div.addEventListener('mouseenter', function() { this.style.background = 'black'; }); });
额外提醒
你的循环变量x没有用let/const声明,会变成全局变量,建议加上let避免全局变量污染。
内容的提问来源于stack exchange,提问作者Daniel M.
相关产品推荐
相关产品推荐

