最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to count visible 'li' on a search list - Stack Overflow

programmeradmin1浏览0评论

The code below is for a simple search. Im trying to count the visible 'li' on the list and display the total in a div "totalClasses". and then when the user search for a class update the total with only the visible classes(li).

I have tried doing this ('li:visble') but is not working.

ul = document.getElementById('myUl');
li = ul.getElementsByTagName('li');
aa = ul.getElementsByTagName('li:visible');
document.getElementById('totalClasess').innerHTML = (aa.length) + " Results";

function search() {
  var input, filter, ul, li, a, aa;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();
  ul = document.getElementById('myUl');
  li = ul.getElementsByTagName('li');

  for (var i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName('a')[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = '';
    } else {
      li[i].style.display = 'none';
    }
  }
}
<input type="text" id="myInput" onkeyup="search()" placeholder="Search for a class..." title="Type something">
<p class="results">Results</p>
<p id="totalClasess"></p>
<ul id="myUl">
  <li><a href="#" class="header">Section 1</a></li>
  <li><a href="#">Class 1 </a></li>
  <li><a href="#">Class 2</a></li>
  <li><a href="#">Class 3</a></li>
</ul>

The code below is for a simple search. Im trying to count the visible 'li' on the list and display the total in a div "totalClasses". and then when the user search for a class update the total with only the visible classes(li).

I have tried doing this ('li:visble') but is not working.

ul = document.getElementById('myUl');
li = ul.getElementsByTagName('li');
aa = ul.getElementsByTagName('li:visible');
document.getElementById('totalClasess').innerHTML = (aa.length) + " Results";

function search() {
  var input, filter, ul, li, a, aa;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();
  ul = document.getElementById('myUl');
  li = ul.getElementsByTagName('li');

  for (var i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName('a')[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = '';
    } else {
      li[i].style.display = 'none';
    }
  }
}
<input type="text" id="myInput" onkeyup="search()" placeholder="Search for a class..." title="Type something">
<p class="results">Results</p>
<p id="totalClasess"></p>
<ul id="myUl">
  <li><a href="#" class="header">Section 1</a></li>
  <li><a href="#">Class 1 </a></li>
  <li><a href="#">Class 2</a></li>
  <li><a href="#">Class 3</a></li>
</ul>

DEMO: https://jsfiddle.net/52bbqor9/

Share Improve this question edited Jul 17, 2017 at 19:51 Tyler Roper 21.7k6 gold badges35 silver badges58 bronze badges asked Jul 17, 2017 at 19:47 Pedro Pedro 1,4502 gold badges16 silver badges44 bronze badges 1
  • 1 Why the jQuery tag? I don't see any. – j08691 Commented Jul 17, 2017 at 19:52
Add a comment  | 

8 Answers 8

Reset to default 3

you need to update the count everytime you call the event handler. you can do like this:

function search()
{
   var input, filter, ul, li, a, aa;
   input  = document.getElementById('myInput');
   filter = input.value.toUpperCase();
   ul     = document.getElementById('myUl');
   li     = ul.getElementsByTagName('li'); 
   var liCount = 0;
   for(var i=0; i<li.length; i++){
        a = li[i].getElementsByTagName('a')[0];
        if(a.innerHTML.toUpperCase().indexOf(filter) > -1){ 
            li[i].style.display = '';
            liCount++;
        } else {
            li[i].style.display = 'none';
        }
    }
    document.getElementById('totalClasess').innerHTML = liCount + " Results";
}

'li:visible' is not a tag, you are adding a pseudo-selector and hoping for the best, which won't work.

You could go

ul.querySelectorAll('li:visible')

If you don't care about Firefox. If you do, I'd recommend jQuery.

ul.find('li:visible');

I would just store the count of show objects during the search function and update the relevant element at the end of the search function:

function search() {
  var input, filter, ul, li, a, aa, count =0;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();
  ul = document.getElementById('myUl');
  li = ul.getElementsByTagName('li');

  for (var i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName('a')[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = '';
      count++;
    } else {
      li[i].style.display = 'none';
    }
  }
  document.getElementById('totalClasess').innerHTML = count + " Results";
}

Just update the count while searching

var ip = document.getElementById('myInput');
var ul = document.getElementById('myUl');
var li = ul.getElementsByTagName('li');

document.getElementById('totalClasess').innerHTML = (li.length) + " Results";

ip.addEventListener('input', function() {
  var val = this.value.toUpperCase(), idx = 0;

  for (var i = 0; i < li.length; i++) {
    var txt = li[i].textContent.toUpperCase();

    if (txt.indexOf(val) != -1) {
      li[i].style.display = 'block';
      idx++;
    } else {
      li[i].style.display = 'none';
    }

    document.getElementById('totalClasess').innerHTML = idx + " Results";
  }
});
<input type="text" id="myInput" placeholder="Search for a class..." title="Type something">
<p class="results">Results</p>
<p id="totalClasess"></p>
<ul id="myUl">
  <li><a href="#" class="header">Section 1</a></li>
  <li><a href="#">Class 1 </a></li>
  <li><a href="#">Class 2</a></li>
  <li><a href="#">Class 3</a></li>
</ul>

You are attempting to attach an event listener function before the element is loaded. Adding a line will do the trick

document.getElementById('myInput').onkeyup = search;

working code

ul = document.getElementById('myUl');
li = ul.getElementsByTagName('li');

divs = document.querySelectorAll('#myUl > li');
var divsArray = [].slice.call(divs);
var aa = divsArray.filter(function(el) {
    return getComputedStyle(el).display !== "none"
});


document.getElementById('totalClasess').innerHTML = (aa.length) + " Results";

function search() {
  var input, filter, ul, li, a, aa;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();
  ul = document.getElementById('myUl');
  li = ul.getElementsByTagName('li');

  for (var i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName('a')[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = '';
    } else {
      li[i].style.display = 'none';
    }
  };
  var divsArray = [].slice.call(divs);
    aa = divsArray.filter(function(el) {
    return getComputedStyle(el).display !== "none"
});
document.getElementById('totalClasess').innerHTML = (aa.length) + " Results";
}
<input type="text" id="myInput" onkeyup="search()" placeholder="Search for a class..." title="Type something">
<p class="results">Results</p>
<p id="totalClasess"></p>
<ul id="myUl">
  <li><a href="#" class="header">Section 1</a></li>
  <li><a href="#">Class 1 </a></li>
  <li><a href="#">Class 2</a></li>
  <li><a href="#">Class 3</a></li>
</ul>

function search() {
var input,filter,ul,li,a,aa;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById('myUl');
li = ul.getElementsByTagName('li');

for (var i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName('a')[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {

        li[i].style.display = '';
    } else {
        li[i].style.display = 'none';
    }
}

var visibleLi = [];
var items = document.getElementById("myUl").getElementsByTagName("li");
for (var i = 0; i < items.length; i++) {

    if (items[i].style.display != "none") {
        visibleLi.push(items[i]);
    }
}
 document.getElementById('totalClasess').innerHTML = (visibleLi.length) + " 
Results";
}

I have simplified your code:

https://jsfiddle.net/52bbqor9/1/

You can check for an item using the :not() selector, and check to see if something does not exist, such as a class. You then would combine it with querySelectorAll and get the length like this:

let itemCount = document.querySelectorAll('#myUl li:not(.hidden)').length;

As for the :visible Pseudo-class Selector that is a jQuery thing and not a real JavaScript Pseudo-class. I created the class hidden which you can see below.

I then removed your onkeyup in your html and created it in the javascript below (I also changed it to input instead). Otherwise the HTML hasn't changed.

<input type="text" id="myInput" placeholder="Search for a class..." title="Type something">
<p class="results">Results</p>
<p id="totalClasess"></p>
<ul id="myUl">
  <li><a href="#" class="header">Section 1</a></li>
  <li><a href="#">Class 1 </a></li>
  <li><a href="#">Class 2</a></li>
  <li><a href="#">Class 3</a></li>
</ul>

Here is where I created a hidden class that I add/remove based on the input text.

.hidden { display: none; }

Next we search for the item and test against a regular expression like so:

// Get the elements we want to work with
let input = document.querySelector('#myInput');
let list = document.querySelectorAll('#myUl li');
let results = document.querySelector('.results');

// Attach an eventlistener to the search box
input.addEventListener('input', e => {
  // Create a regexp to test against each item
  let search = new RegExp('^' + e.target.value, 'i');
  // Loop through the list of li items
  for (let item of list) {
    // Test the current item
    if (search.test(item.innerText.trim())) {
      // Remove the hidden class if it matches
      item.classList.remove('hidden');
    } else {
      // Add the hidden class if it doesn't match
      item.classList.add('hidden');
    }
  }
  // Get a count of li items without `.hidden`
  results.innerText = 'Results ' + document.querySelectorAll('#myUl li:not(.hidden)').length;
});

The very last thing we do is get a count of all the items that don't have a .hidden class attached to it and show it in the results paragraph tag.

发布评论

评论列表(0)

  1. 暂无评论