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 previousElementSibling and insertBefore

Greg Schudel
Greg Schudel
4,090 Points

questions about properties used from addEventListener....

A few questions...

//function for allowing you to remove/moveup the li through individual remove/moveUp buttons

listUL.addEventListener( 'click', (event) => {

  if (event.target.tagName === 'BUTTON') { //we are we using the event.target again?

        if ( event.target.tagName === 'remove' ) { // why is used again here?

          let li = event.target.parentNode; // this selections anything that in the button's parent correct?
          let ul = li.parentNode; // why does this have to be selected? We already have the parent. Is it because we are selecting the parent of the parent?
          ul.removeChild(li);   

         }

        if (event.target.className === 'moveUp') {

          let li = event.target.parentNode;
          let prevLi = li.previousElementSibling;
          let ul = li.parentNode;
          if (prevLi) {

            ul.insertBefore(li, prevLi);

            }

          } 

   }

});

And another thing, why is my above code always orange and not green. I am using correct markdown from the cheatsheet (i.e. here is my code)

2 Answers

andren
andren
28,558 Points
if (event.target.tagName === 'BUTTON') { //we are we using the event.target again?

This line is used to see if the thing that has been clicked on is a button, since the event listener is attached to the ul element it will be triggered if you click on anything within the ul, not just the buttons, which is why that test is necessary.

if ( event.target.tagName === 'remove' ) { // why is used again here?

That code snippet is actually incorrect, in the video event.target.className is used not event.target.tagName. And the purpose of the line is to check if the button that was clicked on is the "remove" button. And not some other button within the ul like the "up" button.

let li = event.target.parentNode; // this selections anything that in the button's parent correct?

parentNode does indeed return the parent of the element you call it on. In this case that will be the li element that the button is within.

let ul = li.parentNode; // why does this have to be selected? We already have the parent. Is it because we are selecting the parent of the parent?

Correct, as mentioned parentNode returns the parent of the element you call it on. In the previous line you got the parent of the button (which was an li), in this line you are getting the parent of the li.

And another thing, why is my above code always orange and not green. I am using correct markdown from the cheatsheet (i.e. here is my code)

To get code highlighting you need to specify the name of the language right after the first three backticks that you use to open the code box. Like this:

```JavaScript

// Code goes here

```

If you don't specify the name of the language then all of the text will be orange by default.

Greg Schudel
Greg Schudel
4,090 Points
listUL.addEventListener( 'click', (event) => {

  if (event.target.tagName === 'BUTTON') {

I'm still not clear on why event.target is being used here. Are event and target two different properties? Also, why is event being used as an argument in the addEventListener ?? How does javascript reconize it without it being defined? Is it a native keyword to javascript?

andren
andren
28,558 Points

event is an object which contains various methods and properties related to the event that triggered the event listener. The target property contains a reference to the exact element that triggered the event. So they are indeed different things.

The event within the parenthesis is not an argument, it is a parameter for an arrow function. In the above code you pass two things into the addEventListener method, the first is a string and the second is a arrow function. Which means that this entire section of code:

(event) => {
    if (event.target.tagName === 'BUTTON') {
        if (event.target.className === 'remove') { 
            let li = event.target.parentNode; 
            let ul = li.parentNode;
            ul.removeChild(li);
        }

        if (event.target.className === 'moveUp') {
            let li = event.target.parentNode;
            let prevLi = li.previousElementSibling;
            let ul = li.parentNode;
            if (prevLi) {
                ul.insertBefore(li, prevLi);
            }
        }
    }
}

Is only one argument which you pass into the addEventListener method. And you are not executing it, only passing in in as a value. When the event the event listener is attached to is triggered it will call the function you passed to it and it will pass in an event object as the first argument.

Maybe it will become slightly clearer if I refactor the code to use a normal function instead of an arrow function that you are only defining a function, not calling one:

listUL.addEventListener('click', function(event) {
    if (event.target.tagName === 'BUTTON') {
        if (event.target.className === 'remove') {
            let li = event.target.parentNode;
            let ul = li.parentNode; 
            ul.removeChild(li);
        }
        if (event.target.className === 'moveUp') {
            let li = event.target.parentNode;
            let prevLi = li.previousElementSibling;
            let ul = li.parentNode;
            if (prevLi) {
                ul.insertBefore(li, prevLi);
            }
        }
    }
});