简体   繁体   中英

How can this jQuery search filter function be rewritten in pure JavaScript?

How could this jQuery search filter function be rewritten in pure JavaScript? The function looks at all li elements whose parent ul element has the category class and hides/shows them based on their content matching or not matching the input from a field with the search class.

$(function(){
  $('.search').keyup(function(){
    var searchText = $(this).val().toLowerCase();
    $allListElements = $('ul.category > li'),
    $matchingListElements = $allListElements.filter(function(i, el){
      return $(el).text().toLowerCase().indexOf(searchText) !== -1;
    });
    $allListElements.hide();
    $matchingListElements.show();
  });
});

EDIT: I tried the function below, but it only targets the first element with the name class inside of the li element, and won't work on the li element as a whole.

var input = document.getElementById('search');
input.onkeyup = function () {
  var filter = input.value.toUpperCase();
  var lis = document.getElementsByTagName('li');
  for (var i = 0; i < lis.length; i++) {
    var name = lis[i].getElementsByClassName('name')[0].innerHTML;
    if (name.toUpperCase().indexOf(filter) == 0) 
        lis[i].style.display = 'list-item';
    else
        lis[i].style.display = 'none';
  }
}

I've checked your code as is on a simple html page, and it seems to be ok (at least in Chrome):

<html>
<body>
<input id="search"/>
<ul class="filter">
    <li><span class="name">filter</span></li>
    <li><span class="name">fi2lter</span></li>
    <li><span class="name">filter</span></li>
    <li><span class="name">filt3er</span></li>
    <li><span class="name">filter</span></li>
</ul>

<script>
document.getElementById('search').addEventListener('keyup', function () {
  var filterText = this.value.toLowerCase(),
  lis = document.querySelectorAll('.filter li'),
  i;
  for (i = 0; i < lis.length; i++) {
    if (filterText === '' || getText(lis[i]).toLowerCase().indexOf(filterText) > -1) {
      lis[i].style.display = 'block';
    }
    else {
      lis[i].style.display = 'none';
    }
  }
});

getText = function( elem ) {
    var node,
        ret = "",
        i = 0,
        nodeType = elem.nodeType;

    if ( !nodeType ) {
        // If no nodeType, this is expected to be an array
        while ( (node = elem[i++]) ) {
            // Do not traverse comment nodes
            ret += getText( node );
        }
    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
        // Use textContent for elements
        // innerText usage removed for consistency of new lines (jQuery #11153)
        if ( typeof elem.textContent === "string" ) {
            return elem.textContent;
        } else {
            // Traverse its children
            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                ret += getText( elem );
            }
        }
    } else if ( nodeType === 3 || nodeType === 4 ) {
        return elem.nodeValue;
    }
    // Do not include comment or processing instruction nodes

    return ret;
};

</script>
</body>
</html>

As I commented on Anton L's answer (thank you again for your help Anton), I was looking for JavaScript that's functionally identical to the jQuery code I provided. There weren't many examples of filtering in pure JavaScript, but I did find a lot of examples in jQuery, so I'm posting my solution as an answer here in case someone else finds it helpful.

HTML:

<input id="search"/>
<ul class="filter">
  <li>FIlter</li>
  <li>fi2lter</li>
  <li>filter</li>
  <li>filt3er</li>
  <li>filter</li>
</ul>

JavaScript:

document.getElementById('search').addEventListener('keyup', function () {
  var filterText = this.value.toLowerCase(),
  lis = document.querySelectorAll('.filter li'),
  i;
  for (i = 0; i < lis.length; i++) {
    if (filterText === '' || lis[i].innerHTML.toLowerCase().indexOf(filterText) > -1) {
      lis[i].style.display = 'block';
    }
    else {
      lis[i].style.display = 'none';
    }
  }
});

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