Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialfabiopantano
8,683 PointsHide spoiler in pure Javascript
Hi all, I'm trying to replicate the hiding spoiler step in pure javascript with the following code:
var el = document.getElementsByTagName("span");
var container = el.parentNode;
container.removeChild(el);
It doesn't work. I get "TypeError: Cannot read property 'removeChild' of undefined".
Any help?
Thanks in advanced!
3 Answers
Sean T. Unwin
28,690 PointsHi Fabio,
This is happening because you are using getElementsByTagName()
. This returns an HTML Collection object.
Currently, el
is that HTML Collection so the removeChild
method fails as el
is not an element, hence the TypeError
- it is expecting one object type while you are giving a different type.
There are a few ways to deal with this. I will show you two three, with the last one two using a different method call altogether.
Edit: As Hugo Paz pointed out there is or will be more than one span throughout the course of this lesson, and through a fun little code challenge with him, I have added a third method at the end of this post.
The first method, while still using getElementsByTagName()
, is to access the item in the Collection. You can do this just as you would access an array item. Since we know that there is only one span
element the length (by checking el.length
) is 1 so we can access that first item and grab it's parentNode
with:
var container = el[0].parentNode;
Then to remove you would do:
container.removeChild(el[0]);
The second method is to use querySelector
since we only have one element to grab. As an aside, if we were grabbing more than one, say all the spans, we could use querySelectorAll
- this is like jQuery's element selector where you can grab a list of elements by type, class, or id or multiples of each.
By using querySelector
, you will only have to change a portion of one line of code you have currently. That would be to change getElementsByTagName
to querySelector
, which would look like:
var el = document.querySelector('span');
This final method is the least amount of code and will remove each element in a list of elements (in this case an instance of a NodeList), regardless of parent.
var elList = document.querySelectorAll('span');
Array.prototype.forEach.call(elList, function(elListItem) {
elListItem.parentNode.removeChild(elListItem);
});
I hope this helps to clarify for you. :)
Hugo Paz
15,622 PointsAfter some tinkering i found a solution, though it might not be the simplest.
var el = document.getElementsByTagName("span");
var size = el.length;
var array = [];
for(var i=0;i<size;i++){
array.push(el[i]);
}
function removeNode(value){
parent = value.parentNode;
parent.removeChild(value);
}
array.forEach(removeNode);
Sean T. Unwin
28,690 PointsNice. I started out with the same strategy and had practically the same code that you posted (you're not using the var
keyword before the parent
variable in your function which will cause that variable to enter the global namespace). I was about to post it until I saw you already had.
Like you, I felt it could be better. I have appended my original answer to include the following.
var elList = document.querySelectorAll('span');
Array.prototype.forEach.call(elList, function(elListItem) {
elListItem.parentNode.removeChild(elListItem);
});
By the way, it was fun bouncing around with you. Have an upvote! :)
pauloliva
7,889 PointsAwesome examples!
fabiopantano
8,683 PointsThanks Sean! I forgotten that getElementsByTagName() return an HTML collection object. It works now.
Thanks Hugo too! :)
Hugo Paz
15,622 PointsHugo Paz
15,622 PointsActually there are 2 span elements. I was working on a solution but for some reason the loop fails after running once.
This deletes the first span but then i get an error on the second one "Cannot read property 'parentNode' of undefined".
Sean T. Unwin
28,690 PointsSean T. Unwin
28,690 PointsHugo Paz,
I only had one span in the Workspace and the video is showing only one as well.
Have you confirmed the value of your
size
variable?Also, if there are more than one, do they have the same parent?
Hugo Paz
15,622 PointsHugo Paz
15,622 PointsThere are 2 span and the size variable value is 2.
Here is the html
Sean T. Unwin
28,690 PointsSean T. Unwin
28,690 PointsI see. They have different parents as well.