Problem
I need a function to get the value of the name attribute of each element with class=”class”. I was wondering what is the best way to do this, performance-wise.
Currently I’m using jQuery and doing it like this:
$("#Button").click(function() {
var myElements = $(".class");
for (var i=0;i<myElements.length;i++) {
alert(myElements.eq(i).attr("name"));
}
});
Alert is just to show what it does, of course. For the following HTML:
<input type="checkbox" class="class" name="1">
<input type="checkbox" class="nope" name="2">
<input type="checkbox" class="class" name="3">
It would issue:
alert("1")
alert("3")
I was wondering if using pure Javascript would be faster, or if there is any other (better) way of doing it. I apologize if this question is not on this website’s scope, please move it to Stackoverflow if that’s the case.
Solution
Pure JS vs jQuery
Pure JavaScript will be significantly faster as you can see by this jsPerf which pits document.getElementByClassName
vs the jQuery selector. Here are the results for Chrome 25:
$('.class')
– 4355 operations per secondgetElementsByClassName('class')
– 94636 operations per second
As you can see, for this simple operation the jQuery option is approximately 22 times slower than the pure-JavaScript equivalent. You can easily see why this is the case by checking out the jQuery development source, since the jQuery ‘selector function’ is so general it needs to do a lot of checks to see what the input is before it can act upon it.
Pure JS implementation
I’ve left the jQuery click
event in as it looks like you already have a dependency on jQuery so no point changing the way you’re hooking up your events.
$("#Button").click(function() {
var items = document.getElementsByClassName('class');
for (var i = 0; i < items.length; i++)
alert(items[i].name);
});
getElementsByClassName
Also note that I used getElementsByClassName
. It is pretty important to choose the ideal selector if you care about performance. Since we care about all elements with a certain class we can immediately dismiss the others like getElementsByTagName
and querySelectorAll
and opt for the function that was built for finding elements of a particular class.
jQuery implementation
This would be my implementation using jQuery, notice that I didn’t bother getting the jQuery object for this
(ie. $(this)
) because the plain JavaScript attribute is much easier in this case.
$("#Button").click(function() {
$(".class").each(function() {
alert(this.name);
});
});
Instead of storing them in an array, you can use $.each
function for looping through them. Like this:
$("#Button").click(function() {
$(".class").each( function() {
alert( $(this).attr("name") );
}
});
To do this is in ‘pure’ JavaScript, you do something like this, if using ES6 syntax:
var elements = document.getElementsByClassName('class');
elements.forEach(e => { alert(e.name) });
For any browsers not supporting ES6 (including all versions of IE):
var elements = document.getElementsByClassName('class');
elements.forEach(function(e) { alert(e.name); });
If IE8 support is required:
var elements = document.querySelectorAll('.class');
for (var i = 0; i < elements.length; i++) {
alert(elements[i].name);
}
Which will be a bit faster compared to using jQuery. However, jQuery will still be the shortest code:
$('.class').each(e => { alert(e.name); });
You can use document.querySelectorAll
to retrieve the desired elements:
var namedEls = document.querySelectorAll('input.class');
for (var i=0;i<namedEls.length;i+=1){
console.log(namedEls[i].name);
} //=> 1, 3
Or as one liner to retrieve names as Array
:
var names = [].slice.call(document.querySelectorAll('input.class'))
.map(function(el){return el.name});
//=> names is now [1,3]
parent.querySelectorAll([name='value']);
Depending on your knowledge of your Dom, can be super efficient; you can select the parent node to search within or just go document if you have no specific Dom knowledge.
If using custom elements or custom name space it can be very powerful and requires no library add ons. Works in all modern browsers.
The platform is growing and can now do amazing things.