选择奇数偶数孩子,不包括隐藏的孩子

时间:2014-09-26 10:55:34

标签: css css3 css-selectors

第2行和第3行之间是隐藏的<div>。我不希望从odd/even css规则中取出那个。 什么是使这个工作的最佳方法? http://jsfiddle.net/k0wzoweh/

enter image description here

<style>
.box:not(.hidden):nth-child(even) {background: green}
.box:not(.hidden):nth-child(odd) {background: orange}
.hidden {display:none;}
</style>
<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>

注意:可以有多个hidden元素。

9 个答案:

答案 0 :(得分:34)

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

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

:not(.hidden)
.hidden {display:none;}

.wrap {
  line-height: 1.2em;
  
  background-color: orange; 
  background-image: linear-gradient(transparent 50%, green 50%);
  background-size: 100% 2.4em;
}

答案 1 :(得分:14)

伪选择者不会叠加,因此: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 - 我现在无法想到。

答案 2 :(得分:7)

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

答案 3 :(得分:5)

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

&#13;
&#13;
.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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 4 :(得分:3)

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

$(“tr:visible:even”)。css(“background-color”,“”); //清除所有行的属性

$(“tr:visible:even”)。css(“background-color”,“#ddddff”); //设置偶数行的属性

(将您的表名添加到选择器以更具体) (使用:甚至使它跳过标题行)

答案 5 :(得分:2)

感谢Joe(+1)指出 css伪选择器规则以及我可以在jQuery中使用1:1的PHP代码,如下所示:

var classToAdd = visibleBoxes%2 ? 'even' : 'odd' ;
$(this).addClass(classToAdd)

答案 6 :(得分:1)

正如 @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>

答案 7 :(得分: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;
      }
    }
  }
}

答案 8 :(得分:-1)

另一种方式,尽管在边缘方面,还是有一个额外的<tbody>并在那里移动或复制行。或者,如果使用OPs示例,则额外的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>