【问题标题】:CSS selector for first td in each column that is not empty每列非空的第一个 td 的 CSS 选择器
【发布时间】:2015-09-27 04:59:40
【问题描述】:

是否有任何选择器为每列仅选择第一个非空单元格,即下面代码示例中包含 2、3 和 4 的单元格?

<table>
  <tbody>
    <tr>
      <td></td>
      <td><span class='a'>2</span></td>
      <td><span class='a'>3</span></td>
    </tr>
    <tr>
      <td><span class='a'>4</span></td>
      <td><span class='a'>5</span></td>
      <td><span class='a'>6</span></td>
    </tr>
  </tbody>
</table>

我当前的解决方案有多个具有固定列号的选择器,这对于包含许多列的表并不理想。

$('table tr td:nth-child(1) .a').first()
$('table tr td:nth-child(2) .a').first()
$('table tr td:nth-child(3) .a').first()

【问题讨论】:

  • 不确定我是否理解你的问题。我回答得太早了。您想选择该行的第一个子元素且不为空的元素吗?
  • 第一个不为空的应该是2和4,为什么是3?
  • 我会尝试不同的配方;如果列从左到右,行从上到下,我想从每一列中只选择一个单元格,如果像示例中那样有多行,我想选择最靠近顶行的一个,即不应选择 5 和 6,因为它们“低于”2 和 3
  • 纯 CSS 无法做到这一点,因为没有父选择器。你必须使用 JS。
  • 我明白了,你想在每一列中选择第一个非空元素,但我认为纯 CSS 不可能,因为这些元素不属于同一个父级(兄弟姐妹)。

标签: jquery css css-selectors


【解决方案1】:

如果您知道您的表格将有多少列,那么您也许能够实现这一点。它不会很漂亮,但你可以做到。

  • 首先选择第一个单元格:td:first-child

  • ...但前提是不为空:td:first-child:not(:empty)

  • 现在,如果不为空,请选择第二个:td:nth-child(2):not(:empty)

  • ...但前提是第一个为空:td:first-child:empty+td:not(:empty)

  • 第三个如果不为空,但前提是前两个为空:td:first-child:empty+td:empty+td:not(:empty)

  • ...并使用新的 +td:empty 重复,尽可能多的列可能有前导空单元格。

  • 然后将所有这些选择器用逗号连接起来,形成一个多重选择器:

    td:first-child:not(:empty),
    td:first-child:empty+td:not(:empty),
    td:first-child:empty+td:empty+td:not(:empty),
    td:first-child:empty+td:empty+td:empty+td:not(:empty) {
        /* styles go here */
    }
    

正如我所说,它确实不是漂亮的 CSS。它应该可以满足您的要求,但我不想维护看起来像那样的代码。

如果您事先不知道您的表格可能有多少个空单元格,这个想法也会有些落空,因为您需要编写 CSS 来支持尽可能多的空单元格。

老实说,如果可能的话,我的建议是修改您的 HTML 代码,将类名放入您要选择的元素中。这是一个更清洁的解决方案。

【讨论】:

  • 不幸的是,仔细检查后,这并没有考虑到第一个非空单元格之后的非空单元格。即使使用问题中给出的标记,您也可以看到这一点:jsfiddle.net/BoltClock/y7p3rvLj
【解决方案2】:

按照 HTML 表格的结构方式,就 CSS 而言,单元格无法知道它是其列中匹配或不匹配条件的第 n 个单元格。

理想情况下,您需要类似于:nth-child(An+B of sel) 的内容,但对于列中的单元格(或对于,取决于您如何看待它),因为每个单元格元素都是一行的子元素元素,所以:nth-child() 将没有任何用处。然而,同样来自 selectors-4 的 :nth-column() 的工作方式却大不相同。此外,列是一种抽象,因此无论如何它们都不匹配选择器——只有元素才匹配。

cmets 中有人提到缺少父选择器是不可能的原因。就我个人而言,我想看看他们如何使用这样的功能来实现这一点,因为我只是看不出它与你的问题有什么关系。您不会尝试匹配单元格、行、tbody、表格或其他任何内容的父级。您正在尝试匹配单元格,相对于它们的列,而不是它们的父/行(列组合器所做的事情,但仍然不适用于您的特定场景)。事实上,我刚才所说的恰恰解释了为什么这个论点没有意义。

您能做的最好的事情就是只计算表格中的列数,然后遍历单元格,找到每列中不为空的第一个单元格。如果列数可以变化,或者您只是不想对所有内容进行硬编码,则必须以编程方式构建选择器(假设您最终以某种方式使用选择器 - 有多种方法可以以编程方式解决此问题,但是关键是:您必须以编程方式进行)。

【讨论】:

    【解决方案3】:

    如果您将 Jquery Not 选择器与 Empty 结合使用,
    可以选择所有不为空的 td 元素。

    首先,我遍历所有 TR 元素。
    查找所有不为空的 td 元素。
    然后给第一个不为空的 td 元素着色。

    $('tr').each(function() {
      var $elem = $(this).find('td').not(":empty").first();
      $elem.css('background-color', "red");
    });
    td {
      width: 50px;
      height: 50px;
      border: 1px solid black;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table>
      <tbody>
        <tr>
          <td></td>
          <td><span class='a'>2</span>
          </td>
          <td><span class='a'>3</span>
          </td>
        </tr>
        <tr>
          <td><span class='a'>4</span>
          </td>
          <td><span class='a'>5</span>
          </td>
          <td><span class='a'>6</span>
          </td>
        </tr>
      </tbody>
    </table>

    【讨论】:

    • 第一个不为空的应该是2和4,为什么是3? – @nevermind
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多