I am trying to replace all text fields on a page with labels.
function replaceInputTextFieldsWithValues() {
var inputFields = document.getElementsByTagName("input");
for(var i = 0; i < inputFields.length; i++) {
if(inputFields[i].getAttribute("type")== "text") {
var parent = inputFields[i].parentNode;
var value = inputFields[i].value;
parent.removeChild(inputFields[i]);
var label = document.createElement('label');
label.setAttribute('for', value);
label.innerHTML = value;
parent.appendChild(label);
}
}
}
My HTML document is organized in tables. This function only seems to work on the first element in each table.
On the other hand, when I remove the line:
parent.removeChild(inputFields[i]);
The code seems to work fine. Why is this happening and how do I fix it?
What you get back from
getElementsByTagNameis anHTMLCollection, which is live. (This is true for the othergetElementsByXYZmethods, but notquerySelectorAll.) That means if you remove the element at index0, theHTMLCollection‘s length will go down and you’ll have a new element at index0instead of the one you just removed.Just work your way through it backward and you’ll be fine:
Alternately, convert the
HTMLCollectioninto an array and then loop through the array. (See the live example and code below).Edit: Or, as Chris Shouts points out in the comments, you can just make use of the changing
length, but it’s not quite as simple as Chris’ suggestion because you’re only removing the elements sometimes. It would look like this:Which of these three approaches to use will depend on the situation. Copying to an array gives you a nice static dataset to work with, and if you make sure to release the reference to the
HTMLCollection, you’re giving the browser the opportunity to realize it doesn’t have to keep that list up-to-date when things change, which could reduce overhead. But you’re copying the references briefly, which increases overhead a bit. 🙂Additional: Here’s an example showing this effect, and also showing a fairly efficient (but obscure) way to create an array from a
HTMLCollection:HTML:
JavaScript:
Live copy