I was familiar with working with objects in JavaScript and how to manipulate them. But until today I didn't know that you could do the same with DOM nodes by manipulate the DOM and iterate through nested DOM elements.
Task
Given a list of Pokemon, each Pokemon will be encapsulated in a <div>
with a class of pokemon
. Inside this <div>
are three DOM nodes: An <h3>
indicating the name of Pokemon. A <p>
containing a child <span>
with the class catched
that indicates whether the Pokemon is catched or not.
The goal is to find all Pokemon where catched
is true
and append them as children of the section Catched Pokemon
with the id catched-pokemon
.
HTML
<h1>Pokemon</h1>
<h2 style="color:green">Wanted Pokemon</h2>
<section class='all-pokemon'>
<div class='pokemon'>
<h3>Bulbasaur</h3>
<p>Catched: <span class='catched'>true</p>
</div>
<div class='pokemon'>
<h3>Charmander</h3>
<p>Catched: <span class='catched'>false</p>
</div>
<div class='pokemon'>
<h3>Squirtle</h3>
<p>Catched: <span class='catched'>true</p>
</div>
<div class='pokemon'>
<h3>Pikachu</h3>
<p>Catched: <span class='catched'>false</p>
</div>
<div class='pokemon'>
<h3>Vulpix</h3>
<p>Catched: <span class='catched'>false</p>
</div>
<div class='pokemon'>
<h3>Psyduck</h3>
<p>Catched: <span class='catched'>true</p>
</div>
<div class='pokemon'>
<h3>Machop</h3>
<p>Catched: <span class='catched'>true</p>
</div>
</section>
<h2 style="color:blue">Catched Pokemon</h2>
<section id='catched-pokemon'></section>
Possible Solution
Let's add some JavaScript to manipulate the DOM nodes and put all Pokemon where catched
is true
under the Catched Pokemon
section.
const pokemon = Array.from(document.getElementsByClassName("catched"));
const catched = pokemon.filter((pokemon) => pokemon.innerHTML === "true");
const onlyCatched = document.getElementById("catched-pokemon");
catched.forEach((catched) => {
let parent = catched.parentElement.parentElement;
onlyCatched.appendChild(parent);
});
What's happening here?
We are using the Array.from() method, which is a static method that creates a new, shallow-copied array instance from an iterable or array-like object. We store the <span>
nodes with the class catched
in const pokemon
.
We then use the filter function to go over the new array and return only the Pokemon which innerHTML
value is true
and store it in const catched
.
We now need to get the node where we want to display our new array of all catched Pokemon, and store it in const onlyCatched
.
Lastly, we use a forEach() function to apply changes to all the pokemon stored in the array called catched
.
At the current stage we only had access to the <span>
nodes, but want to show the whole Pokemon node. Therefore, we are using parentElement property twice to first get the <p>
with which the <span>
is surrounded and then the <div>
, which stores all information needed.
Check out the source code. Using console.log will show you what is stored after each step for better understanding.
I am more than happy if you have other solutions to share so everyone can learn from it.
Thanks for your reading and time. I really appreciate it!
Top comments (3)
Nice, I did not know that Array.from also works with array-like object!
It is cleaner syntax then e.g.
Array.prototype.filter.call(pokemon, ....);
Add to the favourite. Thx
Glad you find it useful.