【问题标题】:Why is CSS selector 'table tr:not(tr:nth-child(even))' throwing a TypeError?为什么 CSS 选择器 'table tr:not(tr:nth-child(even))' 会抛出 TypeError?
【发布时间】:2019-01-22 23:39:05
【问题描述】:

为什么这个选择器起作用:

document.querySelectorAll('table tr:not(:nth-child(even))');

虽然此选择器不会(抛出 TypeError):

document.querySelectorAll('table tr:not(tr:nth-child(even))');

var query = (selector) => {
  return document.querySelectorAll(selector);
};
  
try {
  var select_a = 'table tr:not(:nth-child(even))';
  var select_b = 'table tr:not(tr:nth-child(even))';

  query(select_a).forEach((node) => {
    node.style.color = 'red';
  });

  query(select_b).forEach((node) => {
    node.style.color = 'blue';
  });
} catch (e) {
    query('div:nth-child(3)')[0].textContent = e.toString();
}
var query = (selector) => {
  return document.querySelectorAll(selector);
};
  
try {
  var select_a = 'table tr:not(:nth-child(even))';
  var select_b = 'table tr:not(tr:nth-child(even))';

  query(select_a).forEach((node) => {
    node.style.color = 'red';
  });

  query(select_b).forEach((node) => {
    node.style.color = 'blue';
  });
} catch (e) {
    query('div:nth-child(3)')[0].textContent = e.toString();
}
<table>
  <tr>
    <td>row 1 first-name</td>
    <td>row 1 last-name</td>
    <td>row-1 email</td>
  </tr>
  <tr>
    <td>row 2 first-name</td>
    <td>row 2 last-name</td>
    <td>row-2 email</td>
  </tr>
  <tr>
    <td>row 3 first-name</td>
    <td>row 3 last-name</td>
    <td>row-3 email</td>
  </tr>
  <tr>
    <td>row 4 first-name</td>
    <td>row 4 last-name</td>
    <td>row-4 email</td>
  </tr>
  <tr>
    <td>row 5 first-name</td>
    <td>row 5 last-name</td>
    <td>row-5 email</td>
  </tr>
</table>

<div>Why does select_a work but not select_b?</div>

<div></div>

【问题讨论】:

  • 为什么它应该起作用? :-)
  • 因为:not() 只接受一个“简单选择器”,而tr:nth-child(even) 不是。 drafts.csswg.org/selectors-3/#simple-selectors-dfn “简单的选择器可以是类型选择器、通用选择器、属性选择器、类选择器、ID 选择器或伪类。”
  • 认为这是因为 CSS Selector Level 3 语法将 :not() 子句中的选择器限制为 simple-selector,可以是 either “类型”选择器(如tr一个“子类”选择器。根据该规则(这让我有点困惑),同时拥有 tr:next-child() 是错误的,因为两者都是。
  • 我认为这是一个有趣的问题,因为从错误消息中看不出问题是什么。此外,我认为 Selector Level 4 语法放宽了规则并允许“复合”选择器。
  • @Pointy 是的,没错,选择器级别 4 取消了限制,支持 选择器列表。 (“简单/复合/复杂选择器列表是简单、复合或复杂选择器的逗号分隔列表。当类型不重要或在周围散文中指定时,这也称为选择器列表” )

标签: javascript css-selectors


【解决方案1】:

虽然此选择器不会(抛出 TypeError):

document.querySelectorAll('table tr:not(tr:nth-child(even))');

:not() 只接受一个“简单选择器”,而tr:nth-child(even) 不是。

https://drafts.csswg.org/selectors-3/#simple-selectors-dfn:

简单选择器可以是类型选择器、通用选择器、属性选择器、类选择器、ID 选择器或伪类。

Either 是这里的重要关键字。只允许使用其中一种选择器类型,而不是它们的组合。

【讨论】:

    猜你喜欢
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    相关资源
    最近更新 更多