使用jQuery查找具有多个类的前一个元素

5
我得到了这个表格的结构:
<tr class="dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail alert">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="even dossier">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail">
  <td>...</td>
  <td>...</td>
</tr>
<tr class="detail alert">
  <td>...</td>
  <td>...</td>
</tr>

当 tr 元素有 alert 类时,我必须将 alert 类添加到具有 dossier 类的前一个元素。
我尝试使用以下代码:
$("tr.alert").prev("tr.dossier").addClass("alert");

这仅适用于 <tr class="dossier"> 元素。它不适用于 <tr class="even dossier"> 元素。

有人知道如何解决这个问题吗?


$("tr.alert").prevUntil('tr.alert', "tr.dossier").addClass("alert"); - Arun P Johny
这个怎么样:$("tr.alert").prev("tr.dossier, tr.even.dossier").addClass("alert"); - arun bahal
$("tr.alert").prev("tr.dossier, tr.even.dossier").addClass("alert"); 存在相同的问题。 - user3469203
3个回答

6
你可以遍历 tr 元素并检查是否具有类 alert。然后,您可以检查之前具有类 dossier 的元素,并向该元素添加类 alert

$("table tr").each(function() {
  if ($(this).hasClass("alert")) {
    $(this).prevAll("tr.dossier").first().addClass("alert");
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="even dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
</table>


只有在“详细警报”tr紧随“卷宗”元素之后时,此功能才有效。 - user3469203
@user3469203 你想获取具有 dossier 类的第一个前面的元素吗? - Alex Char
@user3469203 很高兴能帮助到你。 - Alex Char
1
你的 $(this).prevAll("tr.dossier").first() 比我的 $($("tr.alert").prevAll("tr.dossier")[0]) 好多了。干得好 :) - AmmarCSE
说实话,@AmmarCSE没有检查其他答案。感谢您的积极评论 :) - Alex Char

4
下面的解释是基于我在答案结尾处的示例代码。
首先,由于您有多个 tr.alert,因此您需要使用 .each(),因为您想将您的类添加到每个 tr.alert 最近的 tr.dossier 上,但保留中间的 tr.dossier 不变。
使用 $("tr.alert").prev("tr.dossier") 只会返回紧接着的元素,而且仅在该元素是带有 dossier 类的 tr 时才返回。如果您想要一个更靠后的元素,则需要使用 $("tr.alert").prevAll("tr.dossier")
然而,仅使用$("tr.alert").prevAll("tr.dossier")将返回每个tr.alert之前具有类dossier的所有tr,然后将它们合并为一个集合。在您的DOM的情况下,jQuery将返回第一个tr.dossier作为第一个tr.alert,并返回最后一个tr.alert的全部三个tr.dossier。这四个结果将被减少为DOM中实际可用的三个项目。
从那里,您可以使用.first().last()选择单个项目,但它只会选择在第一个或最后一个tr.alert之前的tr.dossier,并且不会应用于两者(似乎您需要)。使用.each()将允许您单独处理每个tr.alert并找到其最近的tr.dossier
在这个例子中,具有类名为 dossier 的行具有绿色背景,而那些具有类名为 alert 的行则将字体大小设置为 50px

$("tr.alert").each(function(index, me) {
  $(me).prevAll("tr.dossier").first().addClass("alert");
});
tr.alert {
  font-size: 50px;
}
tr.dossier {
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="even dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
</table>


在选择器中包含类是一个不错的方法。你不需要我代码中额外的if语句。 - Alex Char

1
使用 prevAll()

$($("tr.alert").prevAll("tr.dossier")[0]).addClass("alert");
.alert{
font-weight: bold;
color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<table>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="even dossier">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail">
    <td>...</td>
    <td>...</td>
  </tr>
  <tr class="detail alert">
    <td>...</td>
    <td>...</td>
  </tr>
</table>


我认为 OP 只想将 alert 类添加到前面的一个 dossier 元素。prevAll 获取所有 dossier 元素。 - xZ6a33YaYEfmv
我只需要将alert类添加到前一个具有dossier类的元素中。prevAll()会将alert元素添加到所有先前的dossier元素中。这不是我想要做的。 - user3469203
我已经尝试了Alex Char的解决方案,它起作用了。你的也差不多,所以它可能也会起作用。 - user3469203

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接