ASP.NET视图中JavaScript报错:Cannot read property 'value' of undefined
问题分析与解决方案
你遇到的Uncaught TypeError: Cannot read property 'value' of undefined错误,本质是代码尝试读取undefined对象的value属性——具体来说,就是additional_free或overtime其中一个变量没有找到对应的DOM元素,变成了undefined。咱们来拆解具体原因和解决办法:
1. 核心原因:目标DOM元素未找到
你的代码通过tr.querySelectorAll('.additional_free,.overtime')获取元素并解构赋值,但如果当前触发事件的<tr>里缺少其中一个元素,就会导致解构后的变量为undefined,进而报错。可能的场景包括:
- 部分行未渲染目标输入框:检查ASP.NET代码,确认
Model1[nr_rows].DniOdpracowania和Model1[nr_rows].SaldoNadgodzin在所有行中都有有效值,确保Html.TextBoxFor确实生成了对应的<input>元素(比如某些数据库返回的行可能没有这两个字段值,导致控件未渲染)。 - 类名拼写不一致:仔细核对HTML中的类名(
additional_free、overtime)和JS选择器的拼写,包括大小写、下划线等细节,确保完全匹配。
2. 优化DOM元素定位逻辑
你当前用e.target.parentNode.parentNode获取<tr>,这种方式依赖固定的DOM层级,如果后续HTML结构有变化(比如input外面嵌套了其他元素),就会导致tr指向错误节点,进而找不到目标元素。建议改用更健壮的方式:
const tr = e.target.closest('tr');
closest('tr')会从当前元素向上查找最近的<tr>元素,比多次调用parentNode更稳定,能适配DOM结构的小改动。
3. 增加元素存在性校验
在操作元素前先检查是否存在,避免因元素缺失抛出错误,修改后的JS代码如下:
table.addEventListener('change', function (e) { const classList = e.target.classList; if (classList.contains('start') || classList.contains('end') || classList.contains('gethours')) { const tr = e.target.closest('tr'); if (!tr) return; // 找不到对应行则直接返回 const additional_free = tr.querySelector('.additional_free'); const overtime = tr.querySelector('.overtime'); // 确保两个元素都存在再执行赋值 if (additional_free && overtime) { additional_free.value = overtime.value; } } });
额外注意:修正重复ID问题
你的HTML中所有<td>都用了id="td01",这违反了HTML规范(ID必须唯一)。虽然这不是当前错误的直接原因,但可能引发后续DOM操作的问题,建议改成唯一ID,比如结合nr_rows生成:
<td id="td-${nr_rows}-start">...</td> <td id="td-${nr_rows}-end">...</td>
内容的提问来源于stack exchange,提问作者user12813863
相关产品推荐
相关产品推荐

