# el-table 复选框无法选中问题记录

> 场景:网页使用 Playwright 勾选 Element UI 表格(el-table)中匹配病人的行。

一、问题描述

在 el-table 中勾选匹配病人的行时遇到三个问题:

  1. 表格里**部分行的复选框根本不可选**(被 CSS 隐藏),但代码识别不出来,导致对这些行执行勾选动作。

  2. 对不可选行调用 `locator.click()` / `check()` 时,操作**一直卡在 `waiting...`**,最终报 `Timeout exceeded`(默认等 30 秒,设短超时后等 2 秒)。

  3. 同时,有些行**一开始就已经被勾上了**(`is-checked`),再点会把它取消掉。

二、排查与尝试过程

尝试 1:用 `isDisabled()` 判断可选性 ------ 失败

原以为不可选行会有 `disabled` 属性。但打印两个 `<input>` 的 outerHTML 后发现两者完全一致:

```html

<input type="checkbox" aria-hidden="false" class="el-checkbox__original" value="">

```

都没有 `disabled`,结果 `isDisabled()` 对两行都返回 `false`,`if (!disabled)` 走进了不可选行并卡死。

尝试 2:检查 `pointer-events` / `is-disabled` 类 ------ 方向偏了

打印 `label` 完整 HTML 后发现两行都是 `pointerEvents: auto`、都没有 `is-disabled` 类,即不是 CSS 禁用也不是原生禁用。但第 1 行 label 带 `is-checked`------说明它是**已勾选**,不是不可选。

尝试 3:拿到完整 `<tbody>` 才看到真信号 ------ 成功定位

完整 HTML 显示选择列 `<td>` 的差异:

  • 可选行:`td class="...el-table-column--selection undefined"`

  • 不可选行:`td class="...el-table-column--selection hiddenTdCheckbox"`

**关键差异是选择列 `<td>` 上的 `hiddenTdCheckbox` 类**------它用 CSS 把勾选框藏起来,所以不可选。之前的 `disabled` / `is-disabled` 思路都没打到点。

卡死原因

`click()` 默认要等元素「可见、稳定、能接收事件」,`hiddenTdCheckbox` 行被隐藏,永远不满足,于一直接 `waiting` 直到超时。

三、最终解决方法

1. 用 `hiddenTdCheckbox` 类识别不可选行,提前跳过(真实信号)

```ts

const selClass = (await row.locator('td.el-table-column--selection').getAttribute('class')) ?? '';

if (selClass.includes('hiddenTdCheckbox')) continue; // 不可选,跳过

```

2. 用 `isChecked()` 跳过已勾选行(防止点一下反被取消)

```ts

const input = row.locator('input.el-checkbox__original');

if (await input.isChecked()) continue;

```

3. 用 `evaluate` 触发勾选,彻底避免等待/卡死

```ts

await input.evaluate((el: HTMLInputElement) => el.click());

```

`evaluate` 是浏览器内同步立即执行,不做任何 actionability 等待,不会被隐藏/失稳元素卡住。

4. 兜底:短超时 + `try/catch` 保证不卡流程

```ts

try {

await row.locator('.el-checkbox__inner').click({ timeout: 2000 });

} catch (e) {

console.log('点击失败,跳过:' + (e as Error).message);

}

```

四、完整逻辑

```ts

const n = await rows.count();

for (let i = 0; i < n; i++) {

const row = rows.nth(i);

const selClass = (await row.locator('td.el-table-column--selection').getAttribute('class')) ?? '';

if (selClass.includes('hiddenTdCheckbox')) continue; // 不可选行跳过

const input = row.locator('input.el-checkbox__original');

if (await input.isChecked()) continue; // 已勾选跳过

await input.evaluate((el: HTMLInputElement) => el.click()); // 勾选未选行

}

```

五、核心结论

  • Element UI 表格「不可选」行的判定信号是选择列 `<td>` 的 **`hiddenTdCheckbox` 类(CSS 隐藏)**,不是 `disabled` 属性。

  • 勾选动作用 `evaluate` 触发比 `click()` / `check()` 更稳,不会被隐藏 / 重渲染元素卡住。

  • `force: true` 不是「不等待」,隐藏元素仍会超时,必须用 `hiddenTdCheckbox` 类提前跳过。

相关推荐
雪芽蓝域zzs14 小时前
从零搭建【pnpm+Vue3+TS+Setup+VueRouter4+Pinia+Axios+ElementPlus (unplugin 按需)】仿若依后台
前端·vue.js
燕落南枝14 小时前
HTML 列表标签详解:有序列表、无序列表与描述列表
前端·html
派小心.14 小时前
DAU和MAU怎么计算?先确定活跃事件、用户键和统计窗口
大数据·服务器·前端·人工智能·数据分析
代码猎人14 小时前
前端怎么配合后端完成bug修复
前端
叫我铁汁儿吧14 小时前
JS作用域
前端·面试
定栓14 小时前
Webpack迁到Vite第七节(四):全家桶移除 — 保留项、脚本与数据收尾
前端·webpack·node.js
VimorphTech15 小时前
React 任务轮询,为什么不能只写一个 setInterval?
javascript·typescript
代码猎人15 小时前
前端怎么优化首屏加载速度
前端
代码猎人15 小时前
前端怎么保障项目稳定上线与运行
前端
数据掘金15 小时前
小程序埋点方案的埋点文档怎么自动生成?
前端