You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用CSS选择器根据子元素属性选择列表中第二个启用按钮?

问题

假设有这样的HTML结构:

<ul>
 <li><button disabled/></li>
 <li><button disabled/></li>
 <li><button /></li>
 <li><button /></li>
 <li><button /></li>
</ul>

里面禁用的按钮数量不确定,但肯定是连续排在启用按钮的前面。现在要选中第二个启用的button。

之前试的几个选择器都不好使:

  • 用"ul li:nth-of-type(2) button:not([disabled])":只会检查第二个<li>里的按钮有没有启用,如果这个按钮是禁用的,就找不到任何元素,没法定位到第二个启用的按钮。
  • 用"ul li button:not([disabled]):nth-of-type(2)":因为每个<li>里只有一个button,:nth-of-type(2)根本匹配不到东西。
  • 本来想先把所有启用的button选出来再取第二个,比如写"ul (li button:not([disabled])):nth-of-type(2)",但这种写法语法不对。

注:这个需求是用来写UI测试的,要找到React时间选择器里的第二个可用时间段。

解决方案

有两种可行的方式,看你测试环境支持哪种:

方式一:用CSS :has()选择器(推荐,逻辑清晰)

直接用下面这个选择器就能精准选中目标:

ul li:has(button:not([disabled])):nth-child(2) button

简单说下逻辑:

  1. 先筛选出所有包含启用状态button的<li>;
  2. 在这些筛选后的<li>里挑第二个;
  3. 最后定位到这个<li>里的button,就是你要的第二个启用按钮。

方式二:环境不支持:has()时的替代方案

如果测试工具或浏览器不支持:has(),可以用下面两种办法:

方案1:相邻兄弟选择器

ul li button:not([disabled]) ~ li button:not([disabled])

这个选择器会找到第一个启用按钮后面的第一个启用按钮,也就是第二个启用的按钮——刚好符合题目里禁用按钮都在前面、启用按钮连续的条件。

方案2:用测试框架的API直接取

比如在Playwright或者Cypress里,先获取所有启用的按钮,再选第二个:

// Playwright示例
const enabledButtons = await page.$$('ul li button:not([disabled])');
await enabledButtons[1].click(); // 索引从0开始,第二个元素是索引1
// Cypress示例
cy.get('ul li button:not([disabled])').eq(1).click();

内容的提问来源于stack exchange,提问作者Preston Moore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:43:10