Select odd even child excluding the hidden child

后端 未结 9 1393
暖寄归人
暖寄归人 2020-12-01 23:30

Line 3 is a hidden

. I don\'t want that one to be taken from the odd/even css rule.

What is the best approach to get t

相关标签:
9条回答
  • 2020-12-01 23:49

    Another way, albeit on the fringe side, is to have an extra <tbody> and either move or copy rows there. Or, an extra div wrapper if using OPs example. Copying easiest of course in regards to restoring etc.

    This approach can be useful in some cases.

    Below is a simple example where rows are moved when filtered. And yes, it is ranking of stripper names, found it fitting as we are talking stripes ... hah

    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>

    0 讨论(0)
  • 2020-12-01 23:52

    As @Fateh Khalsa pointed out, I had a similar problem and since I was manipulating my table with JavaScript (jQuery to be precise), I was able to do the following:

    (Note: This assumes use of JavaScript/jQuery which the OP did not state whether or not would be available to them. This answer assumes yes, it would be, and that we may want to toggle visibility of hidden rows at some point.)

    • Inactive records (identified with the CSS class "hideme") are currently visible.
    • Visitor clicks link to hide inactive records from the list.
    • jQuery adds "hidden" CSS class to "hideme" records.
    • jQuery adds additional empty row to the table immediately following the row we just hid, adding CSS classes "hidden" (so it doesn't show) and "skiprowcolor" so we can easily identify these extra rows.

    This process is then reversed when the link is clicked again.

    • Inactive records (identified with the CSS class "hideme") are currently hidden.
    • Visitor clicks link to show inactive records from the list.
    • jQuery removes "hidden" CSS class to "hideme" records.
    • jQuery removes additional empty row to the table immediately following the row we just showed, identified by CSS class "skiprowcolor".

    Here's the JavaScript (jQuery) to do this:

    // 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
        }
    });
    

    The HTML link is simple

    <a href="#" class="toginactive">Hide/Show Hidden Rows</a>
    
    0 讨论(0)
  • 2020-12-01 23:55

    :nth-child() pseudo-class looks through the children tree of the parent to match the valid child (odd, even, etc), therefore when you combine it with :not(.hidden) it won't filter the elements properly.

    Alternatively, we could fake the effect by CSS gradient as follows:

    .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>

    0 讨论(0)
  • 2020-12-01 23:59

    Here's a CSS-only solution:

    .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>

    0 讨论(0)
  • 2020-12-02 00:00

    scss for @tim answer's above, to keep class name changes to a minimum

    $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 讨论(0)
  • 2020-12-02 00:03

    Since my rows are being hidden with js, I found that the easiest approach for me was to just add an additional hidden row after each real row that I hide, and remove the hidden rows when I show the real rows again.

    0 讨论(0)
提交回复
热议问题