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 trialKhem Myrick
Python Web Development Techdegree Graduate 18,701 PointsRemove the list item element stored in firstListItem from the DOM.
Task 3 of this challenge asks that I remove the list item element stored within the variable firstListItem from the DOM. Doing so seems to cause Task 1, "Select the unordered list element and store it in the variable myList" to fail. The only solution I could think of was to try to put tasks 2 and 3 above task 1 so that myList still has an unordered list to work with, but I don't really understand where the unordered list is going to begin with.
<!DOCTYPE html>
<html>
<head>
<title>DOM Manipulation</title>
</head>
<link rel="stylesheet" href="style.css" />
<body>
<ul>
<li id="first">First Item</li>
<li id="second">Second Item</li>
<li id="third">Third Item</li>
</ul>
<script src="app.js"></script>
</body>
</html>
let firstListItem = document.querySelector('#first');
document.removeChild(firstListItem);
let myList = document.querySelector('ul');
3 Answers
Steven Parker
231,270 PointsHere's a few hints:
- the "firstListItem" is not a direct child of the document
- there might be a reason the challenge wanted you to define "myList" first
- don't change the ordering of the code lines
Steven Parker
231,270 PointsSo Khem, we seem to have taken your question pretty far in a different direction, I hope it hasn't been a source of confusion!
Khem Myrick
Python Web Development Techdegree Graduate 18,701 PointsI'm sorry. I thought I clicked the "best answer" button awhile ago. Of course, as soon as I saw that I could just apply the method to the variable, it seemed obvious. (I think I was worried I'd be removing the li from my variable, but not from the DOM somehow).
Also, it's fascinating to think about JS reading each line of HTML white space as a node. That might save me some confusion later on. Thanks!
Joseph Wasden
20,407 PointsI approached this solution slightly differently than you. Rather than trying to use a query selector to get at the childNode, try using the childNodes[i]
method off the myList
parent node. Here's a prompt below. Be sure to check the MDN documentation for examples of how to impliment the removeChild
element off the parent node. Link to docs is below.
let myList = document.querySelector('ul');
let firstListItem = myList.childNodes[1];
//your code here
https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
Steven Parker
231,270 PointsNB: Both uses of "querySelector" are correct in the original code, though your method is also effective.
Joseph Wasden
20,407 PointsFair point, Steven, thank you.
I hadn't tested if using the document.querySelector('#first')
to assign let firstListItem
still produced the desired result when using node.removeChild(), but it seems to work just fine either way.
Steven Parker
231,270 PointsBTW — I am curious if you know why you needed myList.childNodes[1]
instead of myList.childNodes[0]
? And do you know what myList.childNodes[0]
actually represents?
For clarity, brevity, and code robustness you might want to use myList.children[0]
instead.
Joseph Wasden
20,407 PointsTLDR;
After some researching, I would agree that myList.children[0]
would be a much better choice; Most people think of DOM elements when manipulating the DOM and wouldn't naturally account for text or comment nodes that might be included in Node.childNodes.
BTW — I curious if you know why you needed
myList.childNodes[1]
instead ofmyList.childNodes[0]
?
Honestly, I had to do more research, and no, I didn't understand why, not really.
And do you know what
myList.childNodes[0]
actually represents?
From what I've read, childNodes[0]
represents any textual content of an element or attribute. In the case of the example above, it would represent any text in the <ul> tag (right?), which is none. What I'm not sure of is if childNodes[0]
is always reserved for text. I'm also not sure if there is a reserved childNodes
index position for comments. I'd be interested to know more about that, however.
A bit spoilery ahead!
I chose childNodes[i]
as part of my response because the MDN docs seem to rely on Nodes as the element from which to invoke removeChild()
and not Element. Without fully understanding what a Node was, I was hoping (perhaps naively? :) ) to reinforce the link that myList
represented a Node. Using myList.childNodes[i]
to get the first list item would demonstrate it was a Node, and that any of it's children were also Nodes (else why name the property childNodes?). After making this mental connection, the removeChild()
docs I linked to represent the removeChild()
method as Node.removeChild()
, implying that it can be called off of a Node. If the OP had already made the connection that myList
represented a Node, they may have arrived at the idea that you could invoke removeChild()
on myList
to remove the desired Node.
That was my train of thought, all without really understanding what a Node was.
But, now I know a little better about what Node is. So, if I'm correct, Node is an interface, one that Elements (among many other DOM API objects) implement? In other words, in the case of this example, because all present elements use the Node interface, you could call both childNodes
and removeChild()
from any DOM element.
Steven Parker
231,270 PointsSo, myList.childNodes[0] would have been the first item if the <ul> tag had been adjacent to the <li> tag in the HTML file. But since they are on separate lines, it represents the white space in between them as a text node. The fact that just adding or removing white space can change the indexing makes code that relies on node order (without checking it) potentially "brittle". So for most uses, properties that are based on elements instead of nodes will produce more robust code.
Joseph Wasden
20,407 Pointsahh...wow.
Yeah, that's pretty brittle. Thanks for prompting me to think more about this.
Mauricio Hernandez
7,208 PointsGod bless you and your family.
Mauricio Hernandez
7,208 PointsMauricio Hernandez
7,208 PointsGod bless you.