This post examines all the ways multiple DOM elements can be manipulated. That
can be done with a while loop or with recursion when using a live
HTMLCollection.
A common issue for the command-line coder is manipulating multiple elements. It requires usually a loop, but not necessary if going the purely functional way by using recursion.
Here's the manipulated HTML:
<div class="something active">foo</div>
<div class="something active">bar</div>
<div class="something active">baz</div>
<div class="something active">fooz</div>
<button class="button">Deactivate</button>We want to remove those .active classes when the "Deactivate" button is
clicked.
For loop
First let's use the good old for loop as a starting point.
var els = document.querySelectorAll('.something.active')
var button = document.querySelector('.button')
button.addEventListener('click', _removeClasses)
function _removeClasses() {
for (var i = 0; i < els.length; i++) {
els[i].classList.remove('active')
}
}That's not too bad, but we can do better with
Document.getElementsByClassName() to fetch the elements, it returns an
array-like object that is a
live HTMLCollection.
An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.
The below while loop will illustrate the live nature of HTML collections
better.
While loop
// This gives us a live an `HTMLCollection`
var els = document.getElementsByClassName('something active')
var button = document.querySelector('.button')
button.addEventListener('click', _removeClasses)
function _removeClasses() {
while (els[0]) {
els[0].classList.remove('active')
}
}Breakdown:
document.getElementsByClassName()- Returns a live HTMLCollection rather than a nodeList.
while (els[0])Goes on as long as there’s juice left in the collection, the collection updates "live".
els[0].classList.remove('active')When a class name is removed, the element is removed from the collection, hence it's "live".
Whenever there is a while loop, recursion can be used instead.
Recursive function
As a reminder: recursion happens when a function calls itself. Here the
_removeClasses function calls itself after the if (els[0]) stop condition:
var els = document.getElementsByClassName('something active')
var button = document.querySelector('.button')
button.addEventListener('click', _removeClasses)
function _removeClasses() {
els[0].classList.remove('active')
if (els[0]) _removeClasses()
}Recursive function can be broken into 3 parts:
- The business logic:
els[0].classList.remove('active') - The stop condition:
if (els[0]) - The recursion:
_removeClasses()
Demo
Conclusions
For me this was an eye opener in HTMLCollections. Hope it also helped you,
drop a comment if you have something to add.