I am trying to refactor my for loop with .map() and ES6 and I am getting an error message stating ".map is not a function"
//basic tab function
function openContent(tabpages) {
var page = document.getElementsByClassName("content");
// for (i = 0; i < page.length; i++) {
// page[i].style.display = "none";
// }
page.map(page => (page.style.display = "none"));
document.getElementById(tabpages).style.display = "flex";
}
I am trying to refactor my for loop with .map() and ES6 and I am getting an error message stating ".map is not a function"
//basic tab function
function openContent(tabpages) {
var page = document.getElementsByClassName("content");
// for (i = 0; i < page.length; i++) {
// page[i].style.display = "none";
// }
page.map(page => (page.style.display = "none"));
document.getElementById(tabpages).style.display = "flex";
}
Please point me to the right direction.
Share Improve this question edited Nov 10, 2018 at 8:48 Felix Kling 818k181 gold badges1.1k silver badges1.2k bronze badges asked Nov 10, 2018 at 8:26 criscris 2251 gold badge6 silver badges12 bronze badges 03 Answers
Reset to default 3page
is an HTMLCollection which is an Object not an Array. You can extract the object's keys to an array for mapping using Object.keys()
For example:
//basic tab function
function openContent(tabpages) {
var page = document.getElementsByClassName("content");
// for (i = 0; i < page.length; i++) {
// page[i].style.display = "none";
// }
Object.keys(page).map(idx => (page[idx].style.display = "none"));
document.getElementById(tabpages).style.display = "flex";
}
As already mentioned, getElementsByClassName
doesn't return an array, so you cannot call .map
on it.
The simplest way to convert to an array would be to use Array.from
:
var page = Array.from(document.getElementsByClassName("content"));
However, .map
is not the right tool for what you are doing. .map
creates a new array from the return values of the callback. But you don't actually intend to use that array.
You simply want to iterate over all elements. You can do this easily without converting the node list to an array, using for...of
:
for (var page of document.getElementsByClassName("content")) {
page.style.display = "none";
}
Given that you're iterating over the elements, and not — from the code you've posted — doing anything with the Array returned from Array.prototype.map()
Id suggest using document.querySelectorAll()
and NodeList.prototype.forEach()
to iterate over that NodeList:
document.querySelectorAll('.content').forEach( (page) => page.style.display = 'none' );
Although I'd also remend using a class to hide the elements, rather than modifying the inline-styles directly:
document.querySelectorAll('.content').forEach( (page) => page.classList.add('hidden') );
Obviously that does require a CSS definition for the hidden
class-name.
References:
document.querySelectorAll()
.Element.classList
API.NodeList.prototype.forEach()
.