【问题标题】:last-of-type applied to elements that do not existlast-of-type 应用于不存在的元素
【发布时间】:2018-09-19 00:01:44
【问题描述】:

找不到这个确切的问题,所以这里......

我最初想要实现的与this question 基本相同,但用于 Rows 而不是 Divs。经过一些进一步的研究,我不确定我想要达到的目标是否可能以我认为应该的确切方式实现,但这让我发现了最后一种奇怪。

谁能解释一下 last-of-type 在这种情况下是如何工作的?我将 last-of-type 应用于不存在的元素,而不是应用于现有的元素(希望这是有道理的)。

CSS 规则:

.row-detail:last-of-type {
  background-color: red;
}

一个例子:

SampleTable = $('#sampleTable').DataTable();

$('.detailButton').on('click', function() {
	
  var button = $(this);
  var icon = button.find('i.fa');
  icon.toggleClass('fa-eye');
  icon.toggleClass('fa-eye-slash');
  button.blur();
  
  var row = button.closest('tr');
  var dataTableRow = SampleTable.row(row);
  console.log(dataTableRow.child.isShown())
  if (!dataTableRow.child.isShown()) {
    
    dataTableRow.child(buildDetailRows()).show();
  }
  else {
  
    dataTableRow.child.hide();
  }
});

function buildDetailRows() {
  
  return $('<tr class="row-detail"><td>Detail 1</td><td>Detail r1 c1</td><td>Detail r1 c2</td><td>Detail r1 c3</td></tr><tr class="row-detail"><td>Detail 2</td><td>Detail r2 c1</td><td>Detail r2 c2</td><td>Detail r2 c3</td></tr><tr class="row-detail"><td>Detail 3</td><td>Detail r3 c1</td><td>Detail r3 c2</td><td>Detail r3 c3</td></tr>');
}
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#banner-message {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

#banner-message.alt {
  background: #0084ff;
  color: #fff;
  margin-top: 40px;
  width: 200px;
}

#banner-message.alt button {
  background: #fff;
  color: #000;
}

.row-detail:last-of-type {  
  background-color: red;
}
<link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.datatables.net/1.10.18/css/dataTables.bootstrap.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.18/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.18/js/dataTables.bootstrap.min.js"></script>


<div class="table">
  <table id="sampleTable" class="table table-striped table-bordered table-condensed">
    <thead>
      <tr>
        <th>Detail</th>
        <th>Col1</th>
        <th>Col2</th>
        <th>Col3</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <button class="detailButton btn btn-xs btn-primary" data-toggle="button">
            <i class="fa fa-eye"></i>
          </button>
        </td>
        <td>row1 Col1</td>
        <td>row1 Col2</td>
        <td>row1 Col3</td>
      </tr>
      <tr>
         <td>
          <button class="detailButton btn btn-xs btn-primary" data-toggle="button">
            <i class="fa fa-eye"></i>
          </button>
        </td>
        <td>row2 Col1</td>
        <td>row2 Col2</td>
        <td>row2 Col3</td>
      </tr>
      <tr>
         <td>
          <button class="detailButton btn btn-xs btn-primary" data-toggle="button">
            <i class="fa fa-eye"></i>
          </button>
        </td>
        <td>row3 Col1</td>
        <td>row3 Col2</td>
        <td>row3 Col3</td>
      </tr>
    </tbody>
  </table>
</div>

请注意:这有点延迟/滞后/与相同代码的非 jsFiddle 实施略有不同。小提琴,由于某种原因,仅在先前的详细信息行关闭时才应用最后一行的样式 - 它在 jsFiddle 中效果更好。

关键是,当您单击详细信息按钮时,它会创建 DataTable 的子行。这些只是表格行,没什么特别的,但最后一个类型只应用于最后一个表格行中的最后一个子行。

我期望看到的是:

  • 单击 row1 详细信息按钮:第 3 个子行设置样式
  • 单击另一个 详细信息按钮(第一个下方),之前样式的子行是 无样式和新行(作为实际的“最后一个类型”有这个 规则)。

实际发生的情况
除了表格最后一行中的第三个子行之外,没有子行使用“last-of-type”样式设置样式 - 尽管在单击之前不存在。 在 jsFiddle 的情况下,您需要关闭以前的详细信息行以“启用”最后一行的样式 - 如上所述,我的代码库中不需要这个“关闭以前的详细信息” - 似乎做个细微的差别。

jsFillde 更奇怪的是,当所有三个详细信息按钮都处于活动状态时,它会设置最后一行的样式,但只有两个处于活动状态时不会。

顺便说一句,我对 last-child 也有同样的行为。
(使用 Chrome)。

【问题讨论】:

  • 伪类应用于元素,而不是元素类。当您将一个类添加到组合中时,就像您所做的那样,该类的作用就像一个过滤器,并且仅当元素具有该类时才应用伪类。
  • 是的,这是我对伪类的理解“仅当元素具有类时才应用伪类”。我要说的是在您单击按钮之前没有类,因此它应该将该规则应用于新添加的元素(具有匹配的类)......它没有。

标签: javascript html css css-selectors


【解决方案1】:

:last-of-type 中,“类型”指的是标记名——它会在其兄弟姐妹中选择所有最后一个具有该标记名的元素。那么,在这种情况下,它将应用到的元素是 tr 元素,所以它只会在元素是其兄弟元素中的最后一个 tr 时匹配。

请注意,选择器是独立匹配的。您使用.row-detail 进一步限定它的事实对:last-of-type 的匹配方式没有影响。这是两个完全独立的过滤器:“我有 .row-detail 类吗”和“我是兄弟姐妹中的最后一个 tr”。

因此,当您展开第三行时,这将匹配,因为“详细行”添加在所有其他行之后,因此表中的最后一个 tr 也是 .row-detail。当您展开任何其他行时,它匹配,因为最后一个 .row-detail 元素不是其兄弟姐妹中的最后一个 tr

您真正想要的确实 存在于规范中,但目前仅由 Safari 实现::nth-last-child(1 of tr.row-detail):nth-child():nth-last-child()of &lt;selector&gt; 参数将计数限制在与选择器匹配的元素之间。向浏览器供应商提交错误以支持它!

【讨论】:

  • Safari 在版本 9 中与 :matches():not(&lt;complex selector-list&gt;) 和一些其他 4 级功能一起提供了此功能,因此我们有一个面向公众(即不受标志保护)的实现几年了。测试用例:data:text/html,&lt;style&gt;:nth-last-child(1 of .cls) { color: red }&lt;/style&gt;&lt;p class=cls&gt;a&lt;p class=cls&gt;b&lt;p&gt;c
  • 好的,谢谢@Zanthir - 看起来我对 css 规则和选择器感到厌烦 - 你说这只是在 safari 中实现的事实,足以让我继续前进。看起来我对类型(元素?)与类等缺乏完全理解。
猜你喜欢
  • 2017-04-22
  • 1970-01-01
  • 2021-12-20
  • 2017-03-04
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多