Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Learn how to reference a previous sibling with previousElementSibling
property, and to insert a node before an element, with insertBefore
.
For some background on why previousSibling and other similar properties don't always refer to element nodes, check out this MDN article on Whitespace in the DOM.
In the last video,
you saw how the parentNode property
0:00
holds a reference to the parent
node of a given element.
0:03
But there's also a reference
to the previous sibling
0:06
stored in the previous
element sibling property.
0:09
In the MDN page for
previous element sibling,
0:12
the first thing that's probably catching
your eye is non document type child node.
0:15
It's a big name, but
don't worry too much about it.
0:19
You can click over on the left
to read more about it.
0:22
And for now, you can think of it as
a big name for the element object.
0:25
Now the other question you might be having
is why is element in the property name?
0:28
We just learned about parent node,
not parent element node.
0:33
So why isn't this just
called previousSibling?
0:37
Well, there is a previousSibling property,
which is older and
0:40
has better browser support
than previousElementSibling.
0:43
However, the reason for
0:46
avoiding previousSibling will
be easier to see in the console.
0:48
So let's hop over to the browser
where our project is loaded, and
0:51
let's declare a variable li and
store a reference to the last list item.
0:55
The one that contains plums.
1:01
Now let's just type li in
the console to see that element,
1:11
then we can hover over it to
highlight it on the page.
1:15
So now type li.previousSibling
in the console,
1:20
and we see that it contains
something called #text.
1:26
Now if we hover over that
nothing is highlighted.
1:31
So now I'm just going to tap the up
arrow to get this command back but
1:34
this time let's examine
its text content property.
1:38
And here we see that it's
an empty two line string.
1:43
So let's do one more thing.
1:47
I'm going to tap the up arrow twice and
1:48
look at the previous sibling of
the list items previous sibling.
1:51
And I get anther List item and
1:59
hovering over it I see that it's
the one with the lavender inside.
2:01
So what's going on here?
2:06
Well previousSibling gets you
the previous document node,
2:07
which isn't necessarily an HTML element.
2:11
In this case, it's an empty string that
sits between the two list items, and
2:14
helps to format the HTML document itself.
2:18
So, since you can't count on
previousSibling to give you the previous
2:21
HTML element previous element
sibling is the way to go.
2:26
And if you want more
information about this,
2:29
I've included in the teacher's notes.
2:31
So now let's see previous
element sibling in action.
2:34
Let's implement an up button
next to each element, and
2:37
clicking on the up button will
move that element up the list.
2:40
First, let's modify index.html, so
2:45
I'm going to break these list items into
separate lines to make them more readable.
2:47
Then I'll copy the top button,
3:00
paste a new one above it and
change its text to up.
3:03
So now that we have multiple buttons here,
let's put classes on each one so
3:10
we can differentiate them in our handler.
3:14
I'll give the first button the class up,
and the second button the class remove.
3:16
Next, I'll l do the same for
3:24
the other elements by simply copying and
pasting in the two buttons.
3:26
Next, over in ap.js we'll need
to modify our click handler
3:35
to only remove an element if
the target's class name is removed.
3:40
So we can use an if statement for that.
3:45
Within this if block, I'll wrap
the references to the list items and
3:47
parent ul in an if statement.
3:52
Then in the condition we'll check the
target's class name by saying If event.
4:03
target.className == 'remove').
4:08
So next clicks to our new up buttons
will come into this handler, too.
4:17
So we just need to set a similar if
statement to check for the up class name.
4:22
But, once we make our selections,
4:26
how will we rearrange the DOM to
move our target element into place?
4:28
So far, we've only learned about append
child which places the node as the last
4:32
sibling of an element's children.
4:36
So for this,
we can use the insertBefore method,
4:39
which inserts a node before
a referenced element.
4:42
Looking at the syntax for
4:46
insert before, it shows we need
three nodes to use this method.
4:48
We'll call the method on the parentNode,
passing in two arguments.
4:53
The first argument is the new element,
or the element we want to place, and
4:58
the second argument is
the reference element, or
5:02
the element we want our
new node to go before.
5:05
Now, there are a couple
of things to note here.
5:08
One is that if the element you want
to place is already in the DOM,
5:10
you don't need to remove it first.
5:14
That will be taken care of for you
before the element is moved into place.
5:16
And the other thing to note is
that there is no such thing as
5:20
the insertAfter method.
5:22
But you'll see how to handle
that functionality soon.
5:24
So let's switch back to our code,
and we can begin by copying and
5:27
pasting this if statement for
the remove method right below itself.
5:30
Then we can modify this code to
handle clicks to our new up buttons.
5:37
So this condition will check if
the targets class name Is up.
5:41
And we'll still need to get a reference to
the parent of the button, the list item,
5:49
and we'll also need the parent of that,
the ul element, so
5:53
we'll will keep these lines of code,
but we're not removing a child here so,
5:56
I'll delete the removeChild
method from this block.
6:01
And since we want to move the target
list item up, we will need to get its
6:05
previous sibling as a reference which we
can get with previous element sibling.
6:10
So we'll declare a new
variable of prevLi and
6:15
say Li.previousElementSibling.
6:18
And then we'll call insert before,
on the unordered list element,
6:26
passing in the list item to move,
and the previous sibling reference.
6:31
All right, let's save the file and
test this in the browser.
6:46
I'll refresh the page, and
there we see the up buttons.
6:50
I'll click up, and
it looks like it's working.
6:54
But watch what happens when we click
the up button at the top of the list.
7:00
It goes to the bottom.
7:05
Well, this is because of
how insert before works.
7:07
And we can fix this with an if statement.
7:10
So if an element is already a first child,
the previous element sibling will be null.
7:13
So we can test that null value in
an if statement, by saying if (prevLi),
7:20
Run this ul.insertBefore method.
7:31
And now, the insert will run only
if there's a previous sibling.
7:35
Saving a file and
switching back to the browser,
7:39
It looks like we're now
getting the expected behavior.
7:45
Great.
7:48
You need to sign up for Treehouse in order to download course files.
Sign up