1
00:00:02,170 --> 00:00:07,300
Here's the same example we already worked on where we already do select things

2
00:00:07,300 --> 00:00:08,180
and now here

3
00:00:08,200 --> 00:00:13,440
let's start simple and let's select a list item here.

4
00:00:13,450 --> 00:00:18,550
Now of course, you learned about different ways of selecting it and I want to select this second list

5
00:00:18,550 --> 00:00:19,670
item actually.

6
00:00:19,720 --> 00:00:22,510
Now for this second list item,

7
00:00:22,510 --> 00:00:27,730
there are a couple of ways which will not work, since it's the second list item not the first one for

8
00:00:27,730 --> 00:00:28,510
example,

9
00:00:28,600 --> 00:00:35,140
you won't be able to select it with document query selector li because that selects the first matching

10
00:00:35,160 --> 00:00:35,560
element,

11
00:00:35,560 --> 00:00:39,100
so the first list item in this case that is found and that would be this list item,

12
00:00:39,100 --> 00:00:40,720
not this one.

13
00:00:40,720 --> 00:00:48,550
What would work is if you take the class, so .list-item here like this because since this is the

14
00:00:48,550 --> 00:00:51,070
first element with that class, it would work

15
00:00:51,310 --> 00:00:54,260
but maybe you have a setup where this is not the case, let's say

16
00:00:54,590 --> 00:00:56,370
and let's actually change it as such,

17
00:00:56,410 --> 00:00:59,470
on this first list item, you have the same class,

18
00:00:59,590 --> 00:01:04,600
now all of a sudden, this way of selecting also won't work anymore as soon as we reload this page

19
00:01:04,780 --> 00:01:09,950
because now this will select the first match and now that we change this, the first matching list item is

20
00:01:10,040 --> 00:01:10,440
this

21
00:01:10,480 --> 00:01:13,370
list item here now that I reloaded the page.

22
00:01:13,540 --> 00:01:16,170
So, what can we do to select this item then?

23
00:01:16,180 --> 00:01:21,440
Well we can use some DOM traversal techniques which I already showed you. Of course in reality if you

24
00:01:21,440 --> 00:01:27,040
are building this page, you could also add an ID attribute or find other ways of making this uniquely

25
00:01:27,040 --> 00:01:32,260
selectable with the query methods you already learned but it's important to also be available to interpret

26
00:01:32,330 --> 00:01:33,390
the DOM.

27
00:01:33,520 --> 00:01:39,820
So one way of accessing it would be to get access to the parent unordered list element here, to this

28
00:01:39,880 --> 00:01:46,240
element node and then have a look at its child nodes or child elements and then select the second child

29
00:01:46,240 --> 00:01:48,630
here because that would be this list item.

30
00:01:48,730 --> 00:01:49,630
This can be done

31
00:01:52,340 --> 00:02:00,220
here in the console by getting access to the unordered list for example with documents query selector ul,

32
00:02:00,220 --> 00:02:05,830
that gives us the first fitting element so since we only have one unordered list in the document,

33
00:02:05,830 --> 00:02:10,570
it will give us access to unordered list here and now on this unordered list,

34
00:02:10,570 --> 00:02:15,490
of course we can use the query selector to select any elements nested in there but we will have

35
00:02:15,490 --> 00:02:17,430
the same problem as before.

36
00:02:17,470 --> 00:02:21,610
If I search for list items, I get the first matching one which is this,

37
00:02:21,610 --> 00:02:27,730
not this, the same if I use a class so this won't really help us here but what we can do is we can use

38
00:02:27,730 --> 00:02:34,510
some of the things I showed you on the slide, for example you can output children here. If you look at

39
00:02:34,660 --> 00:02:35,770
ul children,

40
00:02:35,770 --> 00:02:42,400
this gives you a so-called HTML collection which is an array-like object in the end, so it's not a real

41
00:02:42,400 --> 00:02:44,710
array but it supports looping and so on,

42
00:02:44,710 --> 00:02:50,920
so what I already showed you and there we know the second element is the one we want, so with ul children

43
00:02:52,590 --> 00:02:55,320
and then index one to get the second element,

44
00:02:55,320 --> 00:03:00,030
we would get access to exactly that list item I was talking about and you'll see it selected here on the

45
00:03:00,030 --> 00:03:00,750
left, right?

46
00:03:00,750 --> 00:03:06,650
If I type this here even without hitting enter, it is already selected. So this would be one way.

47
00:03:06,720 --> 00:03:12,840
This also is a great place to understand the difference between child nodes and child element nodes

48
00:03:13,260 --> 00:03:15,540
in case it's not fully clear yet.

49
00:03:15,720 --> 00:03:22,080
Here I'm using children and this gives me access to all child element nodes, so only child nodes that

50
00:03:22,080 --> 00:03:27,890
are based on HTML tags, HTML elements, text nodes are excluded here.

51
00:03:27,940 --> 00:03:33,120
Now please keep in mind that as I mentioned earlier in this module, text nodes are also part of the

52
00:03:33,120 --> 00:03:39,700
DOM tree, of that tree that is created here by the browser to reflect your HTML document and that there,

53
00:03:39,750 --> 00:03:46,710
even the whitespace which you add in your HTML file for readability reasons is treated as a text

54
00:03:46,710 --> 00:03:49,680
node because it is text in your HTML file,

55
00:03:49,680 --> 00:03:56,740
right? So therefore, actually in our HTML code, here of course I also have a bunch of whitespace in

56
00:03:56,740 --> 00:03:58,660
front of the body and in front of the header

57
00:03:58,690 --> 00:04:01,430
and of course also in front of the list item here,

58
00:04:01,450 --> 00:04:05,310
I also have a line break between the unordered list and the list item.

59
00:04:05,350 --> 00:04:06,310
So here the difference

60
00:04:06,310 --> 00:04:13,030
we can actually see is that children gives me this collection of element nodes that are direct

61
00:04:13,030 --> 00:04:14,830
children of this unordered list,

62
00:04:14,830 --> 00:04:18,960
so no other descendants and also and no other types of nodes.

63
00:04:19,060 --> 00:04:21,390
If we use child nodes instead,

64
00:04:21,550 --> 00:04:27,880
now you see instead of this HTML collection array-like object, we now have a node list array-like

65
00:04:27,910 --> 00:04:28,770
object

66
00:04:28,770 --> 00:04:32,320
and if we output this, indeed we see there's way more content in there.

67
00:04:32,350 --> 00:04:36,040
There are a bunch of text nodes as you can now clearly tell

68
00:04:36,040 --> 00:04:43,240
and of course also our element nodes but also the text nodes because child nodes selects all child nodes,

69
00:04:43,540 --> 00:04:51,280
whereas children only select child element nodes and child nodes therefore also includes text nodes and

70
00:04:51,280 --> 00:05:00,310
here this text for example, in front of this first list item, that is exactly this whitespace which you in the

71
00:05:00,370 --> 00:05:01,880
end have here.

72
00:05:01,880 --> 00:05:07,970
So if we have a look at this text here, data here is actually its text content,

73
00:05:07,970 --> 00:05:13,400
we haven't learned about this yet but where you have text content on element nodes to assign a text

74
00:05:13,430 --> 00:05:20,810
and automatically create a child text node for an element node, data on a text node sets the text of this

75
00:05:20,810 --> 00:05:21,580
text node

76
00:05:21,650 --> 00:05:26,540
and here this is the line break character and then we have a bunch of whitespace thereafter, so a bunch

77
00:05:26,540 --> 00:05:29,790
of empty whitespace and that's just what we have here.

78
00:05:29,870 --> 00:05:38,360
We have a line break after the unordered list and then we have 1, 2, 3, 4, 5, 6 pieces of whitespace here

79
00:05:38,360 --> 00:05:47,660
and that's exactly what we have here we have the line break and then we have 1, 2, 3, 4, 5, 6 pieces of whitespace

80
00:05:47,660 --> 00:05:48,030
here.

81
00:05:48,650 --> 00:05:50,360
So this is this text node,

82
00:05:50,360 --> 00:05:52,200
now why is this not rendered here?

83
00:05:52,220 --> 00:05:57,410
It's not this whitespace in front of the bullet point in case you're wondering. Well it's not rendered

84
00:05:57,770 --> 00:06:05,660
because we have no style that would render it. The default for HTML in most tags is or the default for

85
00:06:05,660 --> 00:06:12,230
the browser for most tags I should say is that it basically omits empty whitespace that has no

86
00:06:12,230 --> 00:06:13,050
purpose,

87
00:06:13,100 --> 00:06:18,710
so whitespace like here between item and one is of course rendered but whitespace at the beginning or

88
00:06:18,710 --> 00:06:24,470
at the end of the content of an element is typically omitted. You can change this with a special style

89
00:06:24,470 --> 00:06:30,560
though if we expand this down there and you go to styles for the unordered list which holds these elements

90
00:06:30,560 --> 00:06:37,060
we just had a look at, so which holds all these child nodes, there if we add whitespace pre,

91
00:06:37,280 --> 00:06:42,350
now you see it here in the left as well, you see there's a bunch of whitespace and the line breaks because

92
00:06:42,350 --> 00:06:49,070
this is some specific CSS styling which overrides the browser default of basically ignoring, leading

93
00:06:49,070 --> 00:06:52,280
or excess whitespace and it renders it instead,

94
00:06:52,280 --> 00:06:57,230
so now instead of ignoring all that extra whitespace, it is getting rendered which is why the list item

95
00:06:57,320 --> 00:06:58,890
is still as big as before

96
00:06:58,970 --> 00:07:02,680
but of course we can see there seems to be some extra content in front of it

97
00:07:02,840 --> 00:07:07,340
and whilst we don't see that here in the elements tab or whilst this is not displayed here as a text

98
00:07:07,340 --> 00:07:09,560
node, we can see it here in the console,

99
00:07:09,560 --> 00:07:13,320
it's just this text node, if I hover over it, it's now selected,

100
00:07:13,430 --> 00:07:19,490
this is this extra whitespace that is getting rendered, a line break and then also all the other

101
00:07:20,120 --> 00:07:22,610
extra pieces of whitespace we have in there.

102
00:07:22,700 --> 00:07:27,890
So that's children and child nodes which allows us to select child nodes, often you want to work with

103
00:07:27,890 --> 00:07:34,080
children because in most cases you're interested in getting access to the child element nodes

104
00:07:34,190 --> 00:07:38,330
but if you need access to all nodes, you can use child nodes like this

105
00:07:38,330 --> 00:07:43,760
and this by the way is then also how you can get access to text nodes, for example with child nodes and

106
00:07:43,760 --> 00:07:51,510
then by using the right index. Now besides children and child nodes, we also have two other useful properties,

107
00:07:51,600 --> 00:07:59,070
let's say you select that the unordered list with query selector ul and there, you want to get access

108
00:07:59,070 --> 00:08:01,470
to the first or the last list item.

109
00:08:01,470 --> 00:08:08,520
Now again, of course you can always do query selector li last of type or first of type, that will

110
00:08:08,520 --> 00:08:14,160
work but for one, this will cost a little bit of performance because query selector has to scan the

111
00:08:14,160 --> 00:08:19,980
entire page and then scan this quite complex CSS query and find the fitting elements and it also

112
00:08:19,980 --> 00:08:23,710
just might be redundant if you already got access to the unordered list any ways.

113
00:08:23,910 --> 00:08:29,580
If you then know you want to work with the first list item, you can use first child to get the first

114
00:08:29,640 --> 00:08:37,140
child node, which in this case is a text node or first element child to get the first element child node

115
00:08:37,320 --> 00:08:39,430
which would be the first list item here

116
00:08:39,660 --> 00:08:42,190
and of course the same is true in the opposite direction.

117
00:08:42,270 --> 00:08:48,780
We also have last child for the last child node which again is a text node here or last element child

118
00:08:48,810 --> 00:08:51,610
which for this unordered list is the last list item.

119
00:08:51,630 --> 00:08:56,880
So this might simply be quicker and cheaper to get access to than with a brand new query on the entire

120
00:08:56,880 --> 00:08:57,940
document.

121
00:08:58,050 --> 00:09:03,670
Of course as a compromise, you could also go for query selector li last of type, that's certainly better than

122
00:09:03,670 --> 00:09:09,570
scanning the entire document but it might still be faster to simply use last element child if you

123
00:09:09,570 --> 00:09:12,690
know that you want the last element child in the end.
