选择奇偶子项,排除隐藏子项

问题描述 投票:0回答:10

第 3 行是隐藏的

<div>
。我不希望从
odd/even css
规则中删除该规则。

让它发挥作用的最佳方法是什么?

.hidden {display:none;}
.box:not(.hidden):nth-child(odd)  { background: orange; }
.box:not(.hidden):nth-child(even) { background: green;  }
<div class="wrap">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box hidden">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
</div>

http://jsfiddle.net/k0wzoweh/

注意:可以有多个

hidden
元素。

css css-selectors
10个回答
43
投票

:nth-child()
伪类会查看父级的子树以匹配有效的子级(
odd
even
等),因此当您将其与
:not(.hidden)
组合时,它不会正确过滤元素。

或者,我们可以通过 CSS 渐变来伪造效果,如下所示:

.hidden {display:none;}

.wrap {
  line-height: 1.2em;
  
  background-color: orange; 
  background-image: linear-gradient(transparent 50%, green 50%);
  background-size: 100% 2.4em;
}
<div class="wrap">
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box hidden">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
</div>


16
投票

伪选择器不会堆叠,因此您的

:not
不会影响
:nth-child
(也不会影响
:nth-of-type
等。

如果您可以求助于 jQuery,则可以在那里使用

:visible
伪选择器,尽管这不是 CSS 规范的一部分。

如果您正在生成 HTML 并且可以更改它,您可以在运行时应用奇数/偶数逻辑,例如在 PHP 中:

foreach ($divs AS $i => $div) {
    echo '<div class="box ' . ($i % 2 ? 'even' : 'odd') . '">x</div>';
}

甚至尝试做一些棘手的事情,比如

.box[class='box']:nth-of-type(even)

不起作用,因为伪选择器甚至不堆叠到属性选择器上。

我不确定是否有任何方法可以纯粹使用 CSS 来完成此操作 - 我现在想不出任何方法。


10
投票

这是一个仅 CSS 的解决方案:

.box {
  background: orange;
}

.box:nth-child(even) {
  background: green;
}

.box.hidden {
  display: none;
}

.box.hidden ~ .box:nth-child(odd) {
  background: green;
}

.box.hidden ~ .box:nth-child(even) {
  background: orange;
}
<div class="wrap">
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box hidden">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
  <div class="box">xx</div>
</div>


8
投票

由于我的行是用js隐藏的,我发现对我来说最简单的方法是在隐藏的每个真实行之后添加一个额外的隐藏行,并在再次显示真实行时删除隐藏行。


4
投票

隐藏要隐藏的行,为每个表行调用 .hide() ,然后调用

$("tr:visible:even").css( "background-color", "" ); // clear attribute for all rows

$("tr:visible:even").css( "background-color", "#ddddff" ); // set attribute for even rows

将表名称添加到选择器中以更加具体。使用

:even
可以跳过标题行。


0
投票

正如 @Fateh Khalsa 指出的那样,我也遇到了类似的问题,并且由于我使用 JavaScript(准确地说是 jQuery)操作我的表格,所以我能够执行以下操作:

(注意:这假设使用 JavaScript/jQuery,OP 没有说明它们是否可用。这个答案假设是的,并且我们可能希望在某个时候切换隐藏行的可见性.)

  • 非活动记录(用 CSS 类“hideme”标识)当前可见。
  • 访客单击链接可隐藏列表中的非活动记录。
  • jQuery 将“隐藏”CSS 类添加到“hideme”记录中。
  • jQuery 在我们刚刚隐藏的行之后立即向表中添加额外的空行,添加 CSS 类“hidden”(因此不会显示)和“skiprowcolor”,以便我们可以轻松识别这些额外的行。

再次单击链接时,此过程会反转。

  • 非活动记录(用 CSS 类“hideme”标识)当前处于隐藏状态。
  • 访问者单击链接即可显示列表中的非活动记录。
  • jQuery 删除“隐藏”CSS 类到“hideme”记录。
  • jQuery 将紧随我们刚刚显示的行之后的表中的附加空行删除,由 CSS 类“skiprowcolor”标识。

这是执行此操作的 JavaScript (jQuery):

// Inactive Row Toggle
$('.toginactive').click(function(e) {
    e.preventDefault();
    if ($(this).hasClass('on')) {
        $(this).removeClass('on');                  // Track that we're no longer hiding rows
        $('.wrap tr.hideme').removeClass('hidden'); // Remove hidden class from inactive rows
        $('.wrap tr.skiprowcolor').remove();        // Remove extra rows added to fix coloring
    } else {
        $(this).addClass('on');                     // Track that we're hiding rows
        $('.wrap tr.hideme').addClass('hidden');    // Add hidden class from inactive rows
        $('.wrap tr.hideme').after('<tr class="hidden skiprowcolor"></tr>');
                                                    // Add extra row after each hidden row to fix coloring
    }
});

HTML 链接很简单

<a href="#" class="toginactive">Hide/Show Hidden Rows</a>

0
投票

上面@tim 答案的scss,以将类名更改保持在最低限度

$selector: "box";
$hidden-selector: "hidden";

.#{$selector} {
  background: orange;

  :nth-child(even) {
    background: green;
  }

  &.#{$hidden-selector} {
    display: none;
  }

  &.#{$hidden-selector} ~ {
    .#{$selector} {
      &:nth-of-type(odd) {
        background: green;
      }

      &:nth-of-type(even) {
        background: orange;
      }
    }
  }
}

0
投票

尝试选择器

.hidden {display:none;}
.box:nth-child(odd of :not(.hidden))  { background: orange; }
.box:nth-child(even of :not(.hidden)) { background: green; }

-1
投票

另一种方法(尽管在边缘侧)是有一个额外的

<tbody>
并在那里移动或复制行。或者,如果使用 OP 示例,则需要一个额外的 div 包装器。当然,在恢复等方面,复制是最简单的。

这种方法在某些情况下可能很有用。

下面是一个简单的示例,其中行在过滤时移动。是的,这是脱衣舞娘名字的排名,发现它很适合我们谈论条纹......哈哈

const Filter = {
  table: null,
  last: {
    tt: null,
    value: ''
  },
  name: function (txt) {
    let tb_d = Filter.table.querySelector('.data'),
        tb_f = Filter.table.querySelector('.filtered'),
        tr = tb_d.querySelectorAll('TR'),
        f = 0
    ;
    tb_f.innerHTML = '';
    if (txt.trim() == '') {
      tb_d.classList.remove('hide');
    } else {
      txt = txt.toLowerCase();
      for (let i = 0; i < tr.length; ++i) {
        let td = tr[i].querySelectorAll('TD')[1];
        if (td.textContent.toLowerCase().includes(txt)) {
          tb_f.appendChild(tr[i].cloneNode(true));
          f = 1;
        }
      }
      if (f)
        tb_d.classList[f ? 'add' : 'remove']('hide');
    }
  },
  key: function (e) {
    const v = e.target.value;
    if (v == Filter.last.value)
      return;
    Filter.last.value = v;
    clearTimeout(Filter.last.tt);
    Filter.last.tt = setTimeout(function () { Filter.name(v); }, 200);
  }
};

Filter.table = document.getElementById('table');
Filter.table.addEventListener('keyup', Filter.key);
table {
  width: 200px;
  border: 3px solid #aaa;
}
tbody tr { background: #e33; }
tbody tr:nth-child(even) { background: #e3e;  }

.hide { display: none; }
<table id="table">
  <thead>
    <tr><th></th><th><input type="text" id="filter" data-keyup="filter" /></th></tr>
    <tr><th>#</th><th>Name</th></tr>
  </thead>
  <tbody class="filtered">
  </tbody>
  <tbody class="data">
    <tr><td>1</td><td>Crystal</td></tr>
    <tr><td>2</td><td>Tiffany</td></tr>
    <tr><td>3</td><td>Amber</td></tr>
    <tr><td>4</td><td>Brandi</td></tr>
    <tr><td>5</td><td>Lola</td></tr>
    <tr><td>6</td><td>Angel</td></tr>
    <tr><td>7</td><td>Ginger</td></tr>
    <tr><td>8</td><td>Candy</td></tr>
  </tbody>
</table>


-2
投票

您可以使用另一种类型的 CSS 选择器:

tbody > tr:nth-of-type(odd)
仅定位
tr
节点,然后,不使用类名来隐藏行,只需用一些元素(隐藏它们)将它们包装起来,这样 CSS 选择器将只匹配奇数表行:

const searchElem = document.querySelector('input');
const tableElem = document.querySelector('table');
const tableBody = document.querySelector('tbody');

function search() {
  const str = searchElem.value.toLowerCase();
  const rows = tableElem.querySelectorAll('tr');
  
  // remove previous wrappers
  // https://stackoverflow.com/a/48573634/104380
  tableBody.querySelectorAll('div').forEach(w => {
    w.replaceWith(...w.childNodes)
  });
  
  // create a wrapper which hides its content:
  const wrapper = document.createElement("div");
  wrapper.setAttribute('hidden', true);
  
  rows.forEach(function(row){
    const text = row.textContent.toLowerCase();
    
    if (str.length && !text.includes(str)) {
      // replace row with wrapper and put the row inside it
      row.replaceWith(wrapper);
      wrapper.appendChild(row);
    }
  });
}

searchElem.addEventListener('keyup', search);
tbody > tr:nth-of-type(odd) { 
  background: pink 
}
<input type="search" placeholder="search">
<table>
  <tbody>
    <tr><td>Apple<td>220
    <tr><td>Watermelon<td>465
    <tr><td>Orange<td>94
    <tr><td>Pear<td>567
    <tr><td>Cherry<td>483
    <tr><td>Strawberry<td>246
    <tr><td>Nectarine<td>558
    <tr><td>Grape<td>535
    <tr><td>Mango<td>450
    <tr><td>Blueberry<td>911
    <tr><td>Pomegranate<td>386
    <tr><td>Carambola<td>351
    <tr><td>Plum<td>607
    <tr><td>Banana<td>292
    <tr><td>Raspberry<td>912
    <tr><td>Mandarin<td>456
    <tr><td>Jackfruit<td>976
    <tr><td>Papaya<td>200
    <tr><td>Kiwi<td>217
    <tr><td>Pineapple<td>710
    <tr><td>Lime<td>983
    <tr><td>Lemon<td>960
    <tr><td>Apricot<td>647
    <tr><td>Grapefruit<td>861
    <tr><td>Melon<td>226
    <tr><td>Coconut<td>868
    <tr><td>Avocado<td>385
    <tr><td>Peach<td>419
  </tbody>
</table>

© www.soinside.com 2019 - 2024. All rights reserved.