表格单元格hover切换复选框时event.currentTarget未定义问题求助
问题修复方案
错误原因分析
当前代码触发Cannot read properties of undefined (reading 'currentTarget')的核心问题:
- 未声明
tableCellsData变量就直接使用,导致数据读取逻辑断裂 - 事件绑定逻辑错误:调用
addEventListener/removeEventListener时直接执行了addCheckboxes()(立即执行函数而非传递引用),同时错误使用带on前缀的事件名(正确应为mouseover/mouseout) - 同一个函数混用两种事件类型,未做事件区分,导致触发时参数混乱
- 手动传递事件参数的方式错误,后续事件触发时
event对象直接变为undefined
修复后的完整实现代码
HTML结构(需给每行添加data-id用于获取行ID)
<table id="table_1" border="1"> <tbody> <tr data-id="1"> <td>任务项1</td> <td>详情内容1</td> <td>待处理</td> <td>2024-05-01</td> <td>备注1</td> </tr> <tr data-id="2"> <td>任务项2</td> <td>详情内容2</td> <td>已完成</td> <td>2024-05-02</td> <td>备注2</td> </tr> <tr data-id="3"> <td>任务项3</td> <td>详情内容3</td> <td>处理中</td> <td>2024-05-03</td> <td>备注3</td> </tr> <tr data-id="4"> <td>任务项4</td> <td>详情内容4</td> <td>待处理</td> <td>2024-05-04</td> <td>备注4</td> </tr> <tr data-id="5"> <td>任务项5</td> <td>详情内容5</td> <td>已完成</td> <td>2024-05-05</td> <td>备注5</td> </tr> <tr data-id="6"> <td>任务项6</td> <td>详情内容6</td> <td>处理中</td> <td>2024-05-06</td> <td>备注6</td> </tr> </tbody> </table>
JavaScript逻辑
// 获取表格及所有行 const taskTable = document.querySelector('#table_1'); const tableRows = Array.from(taskTable.querySelectorAll('tbody tr')); // 存储首列单元格的原始内容,键为行ID const cellOriginalData = new Map(); // 初始化:存储原始数据,绑定事件 tableRows.forEach(row => { const firstCell = row.querySelector('td:first-child'); const rowId = row.dataset.id; cellOriginalData.set(rowId, firstCell.innerHTML); // 绑定鼠标悬停事件 firstCell.addEventListener('mouseover', () => showCheckbox(row)); // 绑定鼠标移出事件 firstCell.addEventListener('mouseout', () => restoreOriginalContent(row)); }); // 显示复选框函数 function showCheckbox(row) { const firstCell = row.querySelector('td:first-child'); // 如果已经是复选框则不重复创建 if (firstCell.querySelector('input[type="checkbox"]')) return; firstCell.innerHTML = ''; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; // 绑定复选框点击事件 checkbox.addEventListener('click', () => handleCheckboxClick(row, checkbox)); firstCell.appendChild(checkbox); } // 恢复原始内容函数 function restoreOriginalContent(row) { const firstCell = row.querySelector('td:first-child'); const checkbox = firstCell.querySelector('input[type="checkbox"]'); // 如果复选框被选中,则不恢复(保持显示所有复选框) if (checkbox?.checked) return; const rowId = row.dataset.id; firstCell.innerHTML = cellOriginalData.get(rowId); } // 复选框点击处理函数 function handleCheckboxClick(row, checkbox) { const rowId = row.dataset.id; // 点击复选框时显示所有行的复选框 tableRows.forEach(r => showCheckbox(r)); if (checkbox.checked) { // 这里可执行删除逻辑,或先标记待删除 console.log(`待删除行ID:${rowId}`); // 如需立即删除,取消注释下面一行 // row.remove(); } }
关键逻辑说明
- 使用
Map存储首列原始内容,通过行ID关联,避免索引混乱 - 分开处理
mouseover和mouseout事件,逻辑更清晰 - 复选框点击时自动显示所有行的复选框,满足需求
- 鼠标移出时,若复选框未选中则恢复原始内容,选中则保持显示
- 通过
row.dataset.id轻松获取行ID,便于后续删除操作
内容的提问来源于stack exchange,提问作者KChimev
相关产品推荐
相关产品推荐

