# 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` 类提前跳过。

相关推荐
葡萄城技术团队1 小时前
给 SpreadJS 单元格装上自动完成
前端
恋猫de小郭1 小时前
Flutter 多窗口重要优化合并,多窗口性能和实用性大幅提升
android·前端·flutter
StudyAndLife1 小时前
开源一个 API 开放平台门户前端:本地 npm run dev 就能逛接口文档
前端
广州华水科技2 小时前
GNSS变形监测一体机在大坝安全监测中的应用与优势分析
前端
hunteritself2 小时前
夯爆了!Qoder 狂肝 2 小时,293 个测试全绿,Credits 一分没扣
前端·人工智能·chrome·深度学习·机器学习
Hilaku2 小时前
为什么前端应该主动去学数据库?
前端·javascript·程序员
朱 欢 庆2 小时前
el-table 表格组件二次封装
javascript·vue.js·elementui
涛涛ing2 小时前
2026年,你终于可以在 `<textarea>` 里定位任意字符了
前端
三8442 小时前
TLS + Web API 安全 · 05 · JWT 与 OAuth2 攻防
前端·安全