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 trial

JavaScript JavaScript and the DOM (Retiring) Traversing the DOM Using parentNode to Traverse Up the DOM

I don't understand very well the utility of parentNode?

I don't seem to grasp why I need parentNode.

Isn't it possible to remove the li's without using parentNode (and removeChild)?

Also, the event.target syntax kinda confuses me.

  list.addEventListener('click', (e) => {
    if (e.target.tagName == 'BUTTON') {
      let li = event.target.parentNode;
      let ul = li.parentNode;
      ul.removeChild(li);
  }
})

2 Answers

Hi Wilfredo,

You need parentNode and removeChild because that is just how the DOM API works — you just have to work with it on its own terms.

As to your second question, whenever an event-listener is fired it is passed an Event object that contains the event details. One of these details is which DOM Element actually triggered the Event. This particular detail is what is stored in event.target.

Thanks Mikis

As for the first answer, are you sure there is no alternative solution?

As for the second, we used event listeners in previous courses and we didn't have to use arguments. So why do I have to use one now? And why do I have to write 'target' after it?

Yes, I'm sure that there is not another way of removing DOM Elements from the DOM Tree that does not involve the parentNode -> childNode dance. Of course, this doesn't mean that people can't create libraries that act as wrappers for such kind of tasks. In fact, the DOM itself does have an API for this called removeChild but it doesn't have sufficient cross-browser support and — like I've said — it's simply doing the parentNode -> childNode thing under the hood.


So event listeners are functions that don't return anything but get passed an Event object as an argument whenever they are called/fired. I'm not sure if you've covered objects yet in your learning but if you haven't, you should do so ASAP; not much will make any sense without this prerequisite knowledge.

In any case, if you're not going to do anything with the Event object that the Browser passes in to your event-listener anytime your chosen event is triggered, you don't have to list it as a parameter:

function (event /*this parameter can be omitted if you don't need it's data */) {
  // For instance
  // If you just wanted to log the time here or something...
  console.log(Date.now())
  // As opposed to actually using that "event" parameter to ... idk...
  // See what it is that got clicked on, or hovered on or whatever
}

This is probably the reason why you didn't see the "event" parameter in previous courses — because you didn't need it, because you weren't going to do anything with it. But now, it seems you need to know what element just got clicked on. So, now, you do need to use the Event object. Specifically, you need the target property on the Event object. If you're wondering what a property is, you need to go learn Object-Oriented Programming. For now, suffice it to say that the target property is where the Browser stores the "target" (naturally) of your event listener. The target will usually be a DOM Element but if you were listening for the scroll event or something, then it would just be the global window. Let me know if that makes sense.

Hey Wifredo,

First of all yes you can achieve the same behaviour though other means. Such as use jQuery or us an ID or class to target the element and then remove them. However here we are using parentNode so that we can learn about DOM traversal.

Also DOM traversal seems useless when you are working on your own project and have access to all your HTML & CSS files. However as you move forward with web programming DOM traversal will become more and more useful to you.

Second: event.target Here is how I understand it:

  • The whole event.target holds a value. Since we are using it inside an event listener, it only comes in action when we mouseover/click on the specific section we are invoking it on.
  • It also hold the value (element) on which we are calling the event listener, thus the "event" & the "target"

In our example we are using the event listener on the whole list section so a number of other elements and buttons also gets stored in the event.target. To element storing everything we are using the if statement. Now event.target only holds the button/list items. Here is how this work:

  1. User performs an action (i.e: mouse over or click)
  2. Our event listener listens to that event and fires up the event object and stores whatever we want in event.target
  3. Now we use whatever is stored in event.target and use for what we need it for. (i.e: get the tag name, or go to the parent node etc.)

Hope that helps.

Hi Bappy,

Wilfredo's question is:

Isn't it possible to remove the li's without using parentNode (and removeChild)?

The answer to this question is not:

Yes, Wilfredo. Use jQuery.

Because jQuery is just a JavaScript library — written in JavaScript. And as far as JavaScript and the DOM goes, there is only one way to remove a DOM Element.

As to the rest of your answer, you might find my response to Wilfredo's follow-up question enlightening. In the case that it's still not clear for you, feel free to ask for clarification ;)

The following is the DOM Removal code from the jQuery library —

function remove( elem, selector, keepData ) {
    var node,
        nodes = selector ? jQuery.filter( selector, elem ) : elem,
        i = 0;

    for ( ; ( node = nodes[ i ] ) != null; i++ ) {
        if ( !keepData && node.nodeType === 1 ) {
            jQuery.cleanData( getAll( node ) );
        }

        if ( node.parentNode ) {
            if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
                setGlobalEval( getAll( node, "script" ) );
            }
            node.parentNode.removeChild( node );
        }
    }

    return elem;
}

Though jQuery simplifies the process of removing a node from the DOM tree, it still relies on parentNode and removeChild to perform this action.