Selecting Elements
How many times have you seen a web app or library that uses jQuery simply
to perform trivial element selection? How many times have you written this:
$(#myElement')
? Or this: $('.myElement')
? Psst… you don’t need jQuery
to select elements! It’s pretty easy with the plain ‘ole DOM API.
- IDs
- CSS Classes
- Tag Names
- Attributes
- Pseudo-classes
- Children
- Descendants
- Exclusion Selectors
- Multiple Selectors
- See a Pattern?
- Filling in the Gaps
- Next in this Series
By ID
jQuery
// returns a jQuery obj w/ 0-1 elements
$('#myElement');
DOM API
// IE 5.5+
document.getElementById('myElement');
…or…
// IE 8+
document.querySelector('#myElement');
Both methods return a single Element
. Note that getElementById
is more efficient
than using querySelector
.
Does jQuery’s syntax provide any advantage here? I don’t see one. Do you?
By CSS Class
jQuery
// returns a jQuery obj w/ all matching elements
$('.myElement');
DOM API
// IE 9+
document.getElementsByClassName('myElement');
…or…
// IE 8+
document.querySelectorAll('.myElement');
The first method returns an HTMLCollection
and is the most efficient of the two choices.
querySelectorAll
always returns a NodeList
.
Again, really simple stuff here. Why bother with jQuery?
By Tag Name
For example, to select all <div>
elements on a page:
jQuery
$('div');
DOM API
// IE 5.5+
document.getElementsByTagName('div');
…or…
// IE 8+
document.querySelectorAll('div');
As expected, querySelectorAll
(which returns a NodeList
) is less efficient than
getElementsByTagName
(which returns an HTMLCollection
).
By Attribute
Select all elements with a “data-foo-bar” attribute that contains a value of “someval”:
jQuery
$('[data-foo-bar="someval"]');
DOM API
// IE 8+
document.querySelectorAll('[data-foo-bar="someval"]');
Again, the DOM API and jQuery syntax is very similar.
By Pseudo-class
Select all fields in a specific form that are currently invalid. Let’s assume our form has an ID of “myForm”.
jQuery
$('#myForm :invalid');
DOM API
// IE 10+
document.querySelectorAll('#myForm :invalid');
Children
Select all children of a specific element. Let’s assume our specific has an ID of “myParent”.
jQuery
$('#myParent').children();
DOM API
// IE 5.5+
// NOTE: This will include comment and text nodes as well.
document.getElementById('myParent').childNodes;
…or…
// IE 9+ (ignores comment & text nodes).
document.getElementById('myParent').children;
But what if we want to only find specific children? Say, only children with an attribute of “ng-click”?
jQuery
$('#myParent').children('[ng-click]');
…or…
$('#myParent > [ng-click]');
DOM API
// IE 8+
document.querySelector('#myParent > [ng-click]');
Descendants
Find all anchor elements under #myParent.
jQuery
$('#myParent A');
DOM API
// IE 8+
document.querySelectorAll('#myParent A');
Excluding Elements
Select all <div>
elements, except those with a CSS class of “ignore”.
jQuery
$('DIV').not('.ignore');
…or…
$('DIV:not(.ignore)');
DOM API
// IE 9+
document.querySelectorAll('DIV:not(.ignore)');
Multiple Selectors
Select all <div>
, <a>
and <script>
elements.
jQuery
$('DIV, A, SCRIPT');
DOM API
// IE 8+
document.querySelectorAll('DIV, A, SCRIPT');
See a Pattern?
If we focus exclusively on selector support, and don’t need to handle anything older than IE8, seems like we could get pretty far simply by replacing jQuery with this:
window.$ = function(selector) {
var selectorType = 'querySelectorAll';
if (selector.indexOf('#') === 0) {
selectorType = 'getElementById';
selector = selector.substr(1, selector.length);
}
return document[selectorType](selector);
};
But I Want More!
For the vast majority of projects, the selectors support baked into the Web API is sufficient. But what if you are unfortunate enough to require IE7 support? In that case, you’ll probably need a little help from some third party code.
Sure, you could just pull in jQuery, but why use such a large codebase when you only need advanced selector support for now? Instead, try a micro-library that focuses exclusively on element selection. Consider Sizzle, which happens to be the selector library that jQuery uses. Selectivizr is another very small selector library that brings CSS3 selector support to very old browsers.
Next
For me: I’ll talk about manipulating DOM elements in the next post.
For you: if I’ve left out any important selectors, let me know in the comments so I can update the post.