简体   繁体   中英

jQuery :not :contains to hide elements not matching array values

I need show just the <li> elements that contain a value in myArray. It works if I only have one value in myArray, but not for multiple values.

  let myArray = ["10/07/2020", "11/07/2020", "12/07/2020", "13/07/2020", "14/07/2020"]  // not working
  let myArray = ["10/07/2020"]  // works
    
        <ul class = "quotes">
          <li class = "quote"> blablabla 11/07/2020 </li>
          <li class = "quote"> blablabla 12/07/2020</li>
          <li class = "quote"> blablabla 12/07/2020</li>
          <li class = "quote"> blablabla 18/07/2020</li>
          <li class = "quote"> blablabla 20/07/2020</li>
          <li class = "quote"> blablabla 22/07/2020</li>
        </ul>

    $(myArray ).each(function () {
      $(".quote:not(:contains("+ this +))").hide();
    });

 

Any idea how to get this to work?

If you're able to apply wrap the relevant text – in this case a date – then the data you're presenting can be somewhat more accessible, and also easier to find and work with.

Therefore I've chosen to use a <time> element to wrap the dates, and produced the following plain-JavaScript approach:

// the array of dates:
let myArray = ["10/07/2020", "11/07/2020", "12/07/2020", "13/07/2020", "14/07/2020"];

// here we find all the <time> elements, using
// document.querySelectorAll(); and then chain
// the resulting NodeList with
// NodeList.prototype.forEach() in order to iterate
// over each of the found Nodes:
document.querySelectorAll('time').forEach(

  // here we use an Arrow function expression, where
  // 'd' is a reference to the current node of the
  // NodeList we're iterating over, and is passed to
  // the function:
  (d) => {

    // we navigate from the <time> Node ('d') to its
    // parentNode the <li>:
    d.parentNode
      // here we access the <li> element's classList
      // property (a list of class-names that the
      // element has):
      .classList
      // and we toggle the 'hidden' class-name, based on
      // the result of the 'switch' the test that follows,
      // here we use Array.prototype.includes() to find
      // if the Array includes an entry equal to the
      // textContent of the <time> element; if so the
      // switch evaluates to (Boolean) true and the
      // class-name is applied, if the expression results
      // in a false, or falsey, value then the class is
      // removed (no error is generated if the class is
      // already present or absent):
      .toggle('hidden', myArray.includes(d.textContent))
  });

 let myArray = ["10/07/2020", "11/07/2020", "12/07/2020", "13/07/2020", "14/07/2020"]; document.querySelectorAll('time').forEach( (d) => { d.parentNode.classList.toggle('hidden', myArray.includes(d.textContent)) });
 .hidden { opacity: 0.4; }
 <ul class="quotes"> <li class="quote"> blablabla <time>11/07/2020</time></li> <li class="quote"> blablabla <time>12/07/2020</time></li> <li class="quote"> blablabla <time>11/07/2020</time></li> <li class="quote"> blablabla <time>18/07/2020</time></li> <li class="quote"> blablabla <time>20/07/2020</time></li> <li class="quote"> blablabla <time>22/07/2020</time></li> </ul>

JS Fiddle demo .

References:

Try this: $(".quote:not(:contains('" + this + "'))").hide();

Update:

$.each(myArray, function(i, v) {
    $(".quote:not(:contains('" + v + "'))").hide();
});

You can loop over all the quote elements and check if its text contains any element in the array using .some .

$('.quote').each(function(){
      let text = $(this).text();
      if(!myArray.some(x => text.includes(x))){
          $(this).hide();
      }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM