修复Uncaught TypeError: 无法读取undefined的add属性问题
解决鼠标悬停方块添加类时的TypeError错误
你遇到的Uncaught TypeError: cannot read properties of undefined (reading 'add')错误,核心原因是事件回调函数里错误地把事件对象当成了DOM元素来操作,两种实现方式的错误点如下:
错误原因分析
第一种实现(createPlayArea内绑定事件):
你给mouseover事件传的回调参数square,实际是鼠标事件对象(MouseEvent),不是创建的方块DOM元素。事件对象没有classList属性,自然会触发undefined报错。第二种实现(querySelectorAll后绑定事件):
回调里直接操作e.classList,但e同样是事件对象,不是方块元素,正确的目标元素应该通过e.target获取。
修正后的两种方案
方案一:在创建方块时直接绑定事件
修改事件回调,通过this(普通函数)或者e.target(箭头函数)获取方块元素:
const squareAmount = 50; const dimensions = '10px'; function createPlayArea() { // 给循环变量i添加let声明,避免全局变量污染 for (let i = 0; i < (squareAmount * squareAmount); i++) { let squares = document.createElement('div') squares.setAttribute('style', 'display: flex; flex-wrap: wrap;') squares.classList.add('square') squares.style.height = dimensions; squares.style.width = dimensions; // 写法1:普通函数用this指向当前方块 squares.addEventListener('mouseover', function() { this.classList.add('darken'); }) // 写法2:箭头函数用e.target获取目标元素 // squares.addEventListener('mouseover', (e) => e.target.classList.add('darken')) playArea.appendChild(squares) } } createPlayArea()
方案二:通过querySelectorAll批量绑定事件
修正回调里的元素获取方式,改用e.target:
const squareAmount = 50; const dimensions = '10px'; function createPlayArea() { for (let i = 0; i < (squareAmount * squareAmount); i++) { let squares = document.createElement('div') squares.setAttribute('style', 'display: flex; flex-wrap: wrap;') squares.classList.add('square') squares.style.height = dimensions; squares.style.width = dimensions; playArea.appendChild(squares) } } createPlayArea() let playSquares = document.querySelectorAll('.square') function pen() { playSquares.forEach(square => square.addEventListener('mouseover', function (e) { // 用e.target获取触发事件的方块元素 e.target.classList.add('darken') })) } pen()
补充说明
事件监听的回调函数默认接收的第一个参数是事件对象,如果要操作触发事件的DOM元素,有两种可靠方式:
- 使用普通函数时,
this会指向绑定事件的元素(箭头函数没有自己的this,所以不能用这种方式) - 通过事件对象的
target属性获取目标元素(兼容所有函数类型)
内容的提问来源于stack exchange,提问作者Nightman9001
相关产品推荐
相关产品推荐

