jQuery不使用eq方法按列名动态获取表格单元格值问题求解
问题说明
- 需求场景:选中表格行后,动态获取指定列对应的单元格值,废弃原有依赖固定列索引的写法
- 原有固定索引实现代码:
var allocationid = $(this).parents("tr").children("td").eq(0).text();
- 适配表格范围:包含
thead、tbody标签的标准结构表格,示例结构如下:
<table> <thead> <tr> <th>ID</th> <th>name</th> </tr> <thead> <tbody> <tr> <td>01</td> <td>joe</td> </tr> </tbody> </table>
- 之前尝试的实现方案:
let colName_NPDId = 'NPDId'; let index1 = $(this).closest("table").find(`thead tr th:contains(${colName_NPDId})`).index(); let npdid = $(this).closest("tr").children("td").eq(index1).text();
- 现存问题:上述代码在jqGrid场景下仅能获取隐藏列的值,无法正确读取可见列的对应值。
失效原因
原方案在jqGrid场景下失效是jqGrid本身的两个渲染特性导致的:
- jqGrid 默认将表头、表体拆分为两个独立的
<table>渲染:表头存放在.ui-jqgrid-hdiv容器下的表格中,表体存放在.ui-jqgrid-bdiv容器下的表格中。在表体行节点上调用$(this).closest("table")只能拿到表体对应的表格,该表格内部没有thead节点,原有选择器无法匹配到正确的表头列。 - jqGrid 会给隐藏列单独添加样式标识,且部分版本会将隐藏列DOM节点放在所有可见列之前,全量匹配
th/td计算索引时会把隐藏节点计入索引值,和实际可见列的顺序错位,最终取值错误。
可行解决方案
适配jqGrid场景的专用实现
直接通过jqGrid的外层容器定位表头,计算索引时仅统计可见列,取值时同步过滤行内隐藏单元格,保证索引对齐:
// 配置要获取的目标列名 const targetColName = 'NPDId'; // 定位当前行所属的jqGrid外层容器 const $gridWrapper = $(this).closest(".ui-jqgrid"); // 计算目标列索引:仅匹配可见表头,做精准匹配避免列名包含关系选错 const colIndex = $gridWrapper.find(".ui-jqgrid-hbox .ui-th-column:visible").filter(function() { return $(this).text().trim() === targetColName; }).index(); // 定位当前行,取对应位置的可见单元格值 const npdid = $(this).closest("tr.jqgrow").find("td:visible").eq(colIndex).text().trim();
兼容普通表格+jqGrid的通用实现
如果同一段代码需要同时适配普通HTML表格和jqGrid场景,可以加场景判断逻辑:
const targetColName = 'NPDId'; const $currentTable = $(this).closest("table"); let colIndex, cellValue; // 判断当前是否为jqGrid场景 if ($currentTable.closest(".ui-jqgrid").length) { const $gridWrapper = $currentTable.closest(".ui-jqgrid"); colIndex = $gridWrapper.find(".ui-th-column:visible").filter(function() { return $(this).text().trim() === targetColName; }).index(); cellValue = $(this).closest("tr.jqgrow").find("td:visible").eq(colIndex).text().trim(); } else { // 普通标准表格取值逻辑 colIndex = $currentTable.find("thead th").filter(function() { return $(this).text().trim() === targetColName; }).index(); cellValue = $(this).closest("tr").children("td").eq(colIndex).text().trim(); }
提示:不要直接使用
:contains选择器做匹配,该选择器是模糊匹配,如果存在列名包含关系(例如同时存在NPDId、NPDIdExtra两列),会出现匹配错误,用.filter()做文本全等判断更稳妥。
内容的提问来源于stack exchange,提问作者Baba Ranjith
相关产品推荐
相关产品推荐

