2

I have an requirement in JS where, i want to get the count of li element which has the same inner value. What is the best way to do it ? I know we can achieve this in Jquery easily using find and contains but i don't want to use jquery.

I want the length of li elements has the Same Value.

For Eg: Say i want to find out how many LI has the value 'A'.

Below is the JS i have tried, which i think is not the best cos if i have say around 10,000 LI then i will have to loop through all the elements get their values and check if its what i want or no, which will surely hit the performance.

Note : LI element is added runtime with their Value.

HTML

<ul class="s_1" id="ULE">
    <li class="r1">A</li>
    <li class="r1">A</li>    
    <li class="r1">B</li>
    <li class="r1">A</li>  
</ul>  

JS

var LI = document.getElementsByClassName('r1');
var cnt = 0;
for(var i=0;i<LI.length;i+=1){
    if(LI[i].innerHTML == 'A'){
        cnt += 1;
    }
}

if(cnt === 4) 
      alert('working good!!');

JS Fiddle

15
  • 1
    What's wrong with your code? If you add another A element, there are 4 of them and the alert happens. Commented Aug 21, 2014 at 7:33
  • Possible that you neee use === instead of == Commented Aug 21, 2014 at 7:34
  • 2
    @Marciano Why would you need to do that when you know it only contains a number? Commented Aug 21, 2014 at 7:35
  • 2
    @Barmar ???innerHTML contains number??? Commented Aug 21, 2014 at 7:36
  • if(cnt === 4) is just adding confusion to your question Commented Aug 21, 2014 at 7:37

2 Answers 2

2

I don't think there is a better way to improve the performance. If you have nothing but the DOM to work with (e.g. if the data is from user input), and not the underlying data structure from which you created the data, AFAICT there is no other structure to collect all of the elements than into an array-type structure, which will then require O(n) time to check every element.

Rather than have a count target, which is therefore dependent on the amount of list elements, try instead a function to handle the data, which increases the convenience somewhat:

function isEveryElementEqual(nodeList) {
    val = nodeList[0].innerHTML;
    for (var i=1; i<nodeList.length; i++) {
        if (nodeList[i].innerHTML !== val) return false;
    }
    return true;
}

var LI = document.getElementsByClassName('r1');

console.log(isEveryElementEqual(LI)); // Returns false with the above HTML
Sign up to request clarification or add additional context in comments.

Comments

1

You don't have to search all <li> in the document. getElementsByClassName can be applied to an element, it will then only search within that element. So you can do:

var LI = document.getElementById('ULE').getElementsByClassName('r1');

DEMO

You can also simplify this with querySelectorAll:

var LI = docuement.querySelectorAll('#ULE .r1');

6 Comments

Excellent point about working only within the desired element. Re your second example, remember that selectors are processed right-to-left, so your simplified solution first finds elements with the class .r1, then eliminates ones that aren't descendants of #ULE. document.getElementById("ULE").querySelectorAll(".r1"); is dramatically faster in a large DOM.
I've read querySelectorAll is slower than getting by id / className.
@Eclecticist: getElementById is dramatically faster than any other method of finding elements. On most browsers that have it, getElementsByClassName is indeed faster than querySelectorAll, presumably because it doesn't have to do full selector parsing and generalized matching. It's not likely to matter, but... :-)
Probably, since it has to parse the selector and then figure out what to do, and what to do is what getting by id and classname does.
@Barmar: I realized I'd made the classic stupid mistake above: I made an assumption about browser code performance which I hadn't tested. But I got lucky this time and was correct (whew): jsperf.com/selector-with-id-root-vs-get-by-id-and-select :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.