1
00:00:01,360 --> 00:00:03,024
<v Jonas>All right.</v>

2
00:00:03,024 --> 00:00:05,460
So let's now implement the same sticky navigation

3
00:00:05,460 --> 00:00:07,980
that we implemented in the last video,

4
00:00:07,980 --> 00:00:12,063
but this time, using the new intersection observer API.

5
00:00:13,670 --> 00:00:17,990
But what actually is the intersection observer API,

6
00:00:17,990 --> 00:00:19,733
and why is it so helpful?

7
00:00:21,383 --> 00:00:23,990
Well, this API allows our code to basically

8
00:00:23,990 --> 00:00:28,400
observe changes to the way that a certain target element

9
00:00:28,400 --> 00:00:31,410
intersects another element, or the way

10
00:00:31,410 --> 00:00:33,413
it intersects the viewport.

11
00:00:34,579 --> 00:00:36,260
And so from this definition alone,

12
00:00:36,260 --> 00:00:38,580
I think you can see that this will actually

13
00:00:38,580 --> 00:00:42,223
be useful in implementing our sticky navigation.

14
00:00:43,378 --> 00:00:45,050
But let's actually start this video by learning

15
00:00:45,050 --> 00:00:49,200
how the intersection observer API actually works,

16
00:00:49,200 --> 00:00:51,560
but without our sticky navigation,

17
00:00:51,560 --> 00:00:54,160
because at the beginning, this can seem

18
00:00:54,160 --> 00:00:58,600
a bit intimidating and confusing, okay?

19
00:00:58,600 --> 00:01:02,250
So to use the intersection observer API,

20
00:01:02,250 --> 00:01:06,483
we need to start by creating a new intersection observer.

21
00:01:07,950 --> 00:01:12,823
So that's IntersectionObserver, just like this,

22
00:01:14,368 --> 00:01:16,880
and then here, we will have to pass in a callback function

23
00:01:16,880 --> 00:01:18,963
and an object of options.

24
00:01:20,110 --> 00:01:22,933
But let's leave that for a bit later, okay?

25
00:01:25,240 --> 00:01:27,650
So let's first store the result of calling this function

26
00:01:27,650 --> 00:01:29,043
into a new variable.

27
00:01:30,914 --> 00:01:33,470
So let's simply call it the observer,

28
00:01:33,470 --> 00:01:36,660
and so now, we have to use this observer

29
00:01:39,059 --> 00:01:40,959
to basically observe a certain target.

30
00:01:42,299 --> 00:01:46,503
So observer and then the method we call on that is observe.

31
00:01:48,228 --> 00:01:49,470
And then here, the target element.

32
00:01:49,470 --> 00:01:51,483
And this one will be section one,

33
00:01:52,810 --> 00:01:56,993
and so this is an element that we already selected before.

34
00:01:58,724 --> 00:01:59,660
So this will make a bit more sense

35
00:01:59,660 --> 00:02:03,360
once we actually create the callback and the options here,

36
00:02:03,360 --> 00:02:04,913
and let's start by the options.

37
00:02:08,946 --> 00:02:12,420
So const, let's call it the observer options,

38
00:02:12,420 --> 00:02:13,253
so obsOptions,

39
00:02:17,103 --> 00:02:18,430
so this is gonna be an object,

40
00:02:18,430 --> 00:02:21,193
and we can also already create the callback function.

41
00:02:22,589 --> 00:02:24,603
Let's simply call this observerCallback.

42
00:02:29,682 --> 00:02:31,600
All right, and of course, we could've created

43
00:02:31,600 --> 00:02:35,010
these right here, because this is where we will now

44
00:02:35,010 --> 00:02:38,540
pass them in, so first the callback,

45
00:02:38,540 --> 00:02:42,453
and second the options, okay?

46
00:02:43,685 --> 00:02:46,490
And so once again, we could've written the function

47
00:02:46,490 --> 00:02:48,930
and the object directly in here,

48
00:02:48,930 --> 00:02:52,043
but I think it's a bit cleaner to have them separately.

49
00:02:53,622 --> 00:02:55,672
So let's now start with the options here,

50
00:02:56,551 --> 00:02:59,860
and so this object needs first a root property.

51
00:02:59,860 --> 00:03:02,160
And this root is the element

52
00:03:02,160 --> 00:03:04,920
that the target is intersecting.

53
00:03:04,920 --> 00:03:07,650
So again, this here is the target,

54
00:03:07,650 --> 00:03:09,890
and the root element will be the element

55
00:03:09,890 --> 00:03:12,993
that we want our target element to intersect.

56
00:03:14,337 --> 00:03:15,720
And again, this will all make more sense

57
00:03:15,720 --> 00:03:17,393
once you see this in action.

58
00:03:18,560 --> 00:03:20,770
So we could now here select an element

59
00:03:20,770 --> 00:03:23,823
or as an alternative, we can write null,

60
00:03:24,905 --> 00:03:27,660
and then we will be able to observe our target element

61
00:03:27,660 --> 00:03:31,077
intersecting the entire viewport, all right?.

62
00:03:32,092 --> 00:03:34,570
So basically, this entire rectangle here,

63
00:03:34,570 --> 00:03:38,820
which shows the current portion of the page, okay?

64
00:03:38,820 --> 00:03:41,743
And then second, we can define a threshold.

65
00:03:43,990 --> 00:03:47,130
Threshold, and this is basically the percentage

66
00:03:47,130 --> 00:03:49,951
of intersection at which

67
00:03:49,951 --> 00:03:51,850
the observer callback will be called,

68
00:03:51,850 --> 00:03:53,133
so this callback here.

69
00:03:54,040 --> 00:03:55,780
So again that's very confusing,

70
00:03:55,780 --> 00:03:59,310
let's just set it to 10%, which is 0.1,

71
00:04:00,160 --> 00:04:02,530
and then when we have this callback function here

72
00:04:02,530 --> 00:04:06,822
also created, then we will see what actually

73
00:04:06,822 --> 00:04:08,870
happens here in practice.

74
00:04:08,870 --> 00:04:09,703
All right.

75
00:04:11,310 --> 00:04:13,940
So this callback function here will get called

76
00:04:13,940 --> 00:04:17,020
each time that the observed element,

77
00:04:17,020 --> 00:04:20,110
so our target element here, is intersecting

78
00:04:20,110 --> 00:04:25,110
the root element at the threshold that we defined, okay?

79
00:04:25,390 --> 00:04:28,380
So take note of this because this is actually

80
00:04:28,380 --> 00:04:31,563
a bit hard to figure out from reading the documentation.

81
00:04:32,961 --> 00:04:34,640
And so it's a good idea to keep note

82
00:04:34,640 --> 00:04:35,933
of what I'm saying here.

83
00:04:37,245 --> 00:04:40,140
So in the current example, whenever the first section,

84
00:04:40,140 --> 00:04:45,000
so our target here, is intersecting the viewport at 10%,

85
00:04:45,000 --> 00:04:48,012
so the viewport, because that's the root,

86
00:04:48,012 --> 00:04:50,263
and 10% because that's the threshold.

87
00:04:51,628 --> 00:04:53,950
So whenever that happens, then this function here

88
00:04:53,950 --> 00:04:57,230
will get called and that's no matter if we are scrolling

89
00:04:57,230 --> 00:04:59,833
up or down, all right?

90
00:05:00,690 --> 00:05:03,703
And this function will get called with two arguments,

91
00:05:04,805 --> 00:05:06,383
and so we can specify them here,

92
00:05:07,684 --> 00:05:11,363
and that's the entries and the observer object itself.

93
00:05:12,560 --> 00:05:15,160
All right, so this object here basically

94
00:05:15,160 --> 00:05:20,120
will also get passed into the callback function, all right?

95
00:05:20,120 --> 00:05:23,200
Now this case, we're only interested in the entries,

96
00:05:23,200 --> 00:05:26,990
but sometimes using the observer is also useful.

97
00:05:26,990 --> 00:05:30,090
Now we can have actually multiple thresholds,

98
00:05:30,090 --> 00:05:32,700
so here we can have an array, and I will do that

99
00:05:32,700 --> 00:05:35,550
in a minute, and so these entries here

100
00:05:35,550 --> 00:05:39,730
are actually an array of the threshold entries, okay,

101
00:05:39,730 --> 00:05:43,610
and so in this case again, there's only one element there,

102
00:05:43,610 --> 00:05:46,410
but let's create a more general function already

103
00:05:46,410 --> 00:05:48,970
which basically loops over these entries

104
00:05:50,550 --> 00:05:52,903
so that we can take a look at all of them.

105
00:05:54,749 --> 00:05:58,134
And so let's just do that, so basically,

106
00:05:58,134 --> 00:05:59,210
simply log them to the console,

107
00:05:59,210 --> 00:06:02,010
and that will already be good enough for us

108
00:06:02,010 --> 00:06:04,473
to take a look at how this all works.

109
00:06:07,371 --> 00:06:10,493
So entry, and so you see I'm using an arrow function here,

110
00:06:11,781 --> 00:06:14,681
but of course any other function would work just the same.

111
00:06:16,800 --> 00:06:18,950
Let's give it a save now, and you see that already,

112
00:06:18,950 --> 00:06:21,823
we get an intersection observer entry,

113
00:06:23,139 --> 00:06:24,689
and so that is this entry here.

114
00:06:26,790 --> 00:06:28,720
And so this is not really interesting yet,

115
00:06:28,720 --> 00:06:31,720
because this is just the first one that we got

116
00:06:31,720 --> 00:06:35,260
and we see that the ratio here is at zero,

117
00:06:35,260 --> 00:06:37,810
but let's see in a second what that actually means.

118
00:06:38,943 --> 00:06:40,450
So I will start scrolling here, and you see

119
00:06:40,450 --> 00:06:44,800
that now we actually got our first real entry here,

120
00:06:44,800 --> 00:06:47,740
which appeared here because our target element

121
00:06:47,740 --> 00:06:49,253
came into the viewport.

122
00:06:50,801 --> 00:06:53,428
So our target element is this whole h1

123
00:06:53,428 --> 00:06:56,654
that's down here, and so you see that it started

124
00:06:56,654 --> 00:06:58,667
intersecting the viewport, okay?

125
00:07:00,091 --> 00:07:02,230
And so our observer is observing that,

126
00:07:03,540 --> 00:07:06,630
and so now here you see that the intersection ratio

127
00:07:07,549 --> 00:07:10,250
at the time that this callback here was called,

128
00:07:10,250 --> 00:07:15,020
so this one here, was at 0.10, and then this.

129
00:07:15,020 --> 00:07:17,880
And so that's exactly the 10% threshold

130
00:07:17,880 --> 00:07:21,290
that we defined over here, all right?

131
00:07:21,290 --> 00:07:24,293
We also get this isIntersecting property,

132
00:07:25,279 --> 00:07:29,100
which in this case is true, and that is because indeed,

133
00:07:29,100 --> 00:07:32,270
our target, so again this whole section here,

134
00:07:32,270 --> 00:07:35,380
is now intersecting the viewport.

135
00:07:35,380 --> 00:07:38,400
And we are looking for the viewport, remember,

136
00:07:38,400 --> 00:07:40,623
because we set the root to null.

137
00:07:42,776 --> 00:07:43,609
All right?

138
00:07:45,346 --> 00:07:47,440
So we also get the target itself here,

139
00:07:47,440 --> 00:07:49,200
and a couple of other stuff,

140
00:07:49,200 --> 00:07:51,960
but the intersection ratio is actually

141
00:07:51,960 --> 00:07:55,883
the most interesting one and also the isIntersecting here.

142
00:07:57,665 --> 00:08:00,293
Okay, so let's scroll down a little bit more,

143
00:08:00,293 --> 00:08:02,230
and let's close this actually,

144
00:08:02,230 --> 00:08:05,280
and let's scroll up again, and so again,

145
00:08:05,280 --> 00:08:07,650
we get a new entry here, and so again,

146
00:08:07,650 --> 00:08:10,420
it should be close to 10%,

147
00:08:10,420 --> 00:08:14,030
but now it happened as we were moving up, right?

148
00:08:14,030 --> 00:08:16,970
And so again it was at 10%, but now,

149
00:08:16,970 --> 00:08:19,543
it is no longer intersecting, okay?

150
00:08:20,564 --> 00:08:23,653
And it's not intersecting because the threshold is at 10.

151
00:08:24,811 --> 00:08:28,480
And so now less than 10% basically of our target here

152
00:08:28,480 --> 00:08:32,700
are inside of the root, so inside of the viewport.

153
00:08:32,700 --> 00:08:35,230
All right, and so you can start to see

154
00:08:35,230 --> 00:08:37,580
why this is more efficient.

155
00:08:37,580 --> 00:08:41,240
So it's because we only get this kind of event here

156
00:08:41,240 --> 00:08:44,420
in the situation that we're actually interested in.

157
00:08:44,420 --> 00:08:48,713
So in this case, that's this threshold of 10%.

158
00:08:50,296 --> 00:08:51,650
Okay, and as we keep scrolling here,

159
00:08:51,650 --> 00:08:53,580
now it will come back again,

160
00:08:53,580 --> 00:08:56,173
and now it is again intersecting,

161
00:08:57,893 --> 00:09:00,680
let's keep scrolling, and all of this here is section one,

162
00:09:00,680 --> 00:09:02,253
and now we got another one.

163
00:09:03,922 --> 00:09:07,860
So let's see, and so now it is back to not intersecting,

164
00:09:07,860 --> 00:09:12,350
because now we no longer have 10% visible, okay?

165
00:09:12,350 --> 00:09:14,930
So you can think of this threshold here

166
00:09:14,930 --> 00:09:18,973
at the percentage that we want to have visible in our root.

167
00:09:20,107 --> 00:09:21,630
So in our viewport in this case, and so,

168
00:09:21,630 --> 00:09:24,850
right now we are back to having less than 10%,

169
00:09:24,850 --> 00:09:28,373
and so it is no longer intersecting here.

170
00:09:29,987 --> 00:09:32,260
And again, if we scroll up a little bit more,

171
00:09:32,260 --> 00:09:35,540
then we get another event here because now

172
00:09:35,540 --> 00:09:40,540
we are back to having 10% intersection ratio, okay?

173
00:09:41,100 --> 00:09:43,880
So this is the very fundamentals of how

174
00:09:43,880 --> 00:09:46,910
the intersection observer API works,

175
00:09:46,910 --> 00:09:50,500
and I confess that it is a bit confusing

176
00:09:50,500 --> 00:09:53,810
and it took me quite some time to figure all of this out,

177
00:09:53,810 --> 00:09:56,510
and so probably the best idea is for you

178
00:09:56,510 --> 00:09:58,720
to stop this video now and explore this

179
00:09:58,720 --> 00:09:59,970
a little bit on your own.

180
00:10:01,182 --> 00:10:03,972
So you can use different threshold values,

181
00:10:03,972 --> 00:10:05,822
and maybe use different targets here,

182
00:10:06,830 --> 00:10:08,220
you can even use different roots,

183
00:10:08,220 --> 00:10:10,840
and so it would be a good idea to experiment

184
00:10:10,840 --> 00:10:13,260
a little bit more with this.

185
00:10:13,260 --> 00:10:17,313
Now what I'm gonna do here is to now specify an array,

186
00:10:18,837 --> 00:10:20,660
so to specify different thresholds,

187
00:10:20,660 --> 00:10:22,490
and one of them is gonna be zero,

188
00:10:22,490 --> 00:10:26,543
and the other one 0.2, so that's 20%.

189
00:10:27,822 --> 00:10:30,510
So 0% here means that basically our callback

190
00:10:30,510 --> 00:10:33,740
will trigger each time that the target element

191
00:10:33,740 --> 00:10:36,223
moves completely out of the view,

192
00:10:37,377 --> 00:10:40,073
and also as soon as it enters the view, okay?

193
00:10:41,358 --> 00:10:42,450
And so that's because the callback function

194
00:10:42,450 --> 00:10:44,960
will be called when the threshold is passed

195
00:10:44,960 --> 00:10:48,313
when moving into the view and when moving out of the view,

196
00:10:49,477 --> 00:10:52,000
and this is really important to remember here.

197
00:10:52,000 --> 00:10:55,100
On the other hand, if we specified one here,

198
00:10:55,100 --> 00:10:57,770
like this, then that means that the callback

199
00:10:57,770 --> 00:11:01,500
will only be called when 100% of the target

200
00:11:01,500 --> 00:11:03,853
is actually visible in the viewport.

201
00:11:05,010 --> 00:11:06,253
So in the case of this section one,

202
00:11:06,253 --> 00:11:10,320
that would be impossible because the section itself

203
00:11:10,320 --> 00:11:12,233
is already bigger than the viewport.

204
00:11:13,756 --> 00:11:16,530
But let's now experiment with zero here,

205
00:11:16,530 --> 00:11:20,820
and so right away, we again get this event here,

206
00:11:20,820 --> 00:11:22,790
and you see that the intersection ratio

207
00:11:22,790 --> 00:11:26,740
is exactly at zero, but it is already intersecting,

208
00:11:26,740 --> 00:11:30,060
and so it's because basically the threshold here

209
00:11:30,060 --> 00:11:31,463
was already passed.

210
00:11:33,630 --> 00:11:35,190
All right?

211
00:11:35,190 --> 00:11:37,090
So I think another one happened there,

212
00:11:38,002 --> 00:11:41,050
let's just reload, oh, and that was probably

213
00:11:41,050 --> 00:11:42,933
from our 20%.

214
00:11:44,700 --> 00:11:47,525
Yep, so you see, this is the 20 threshold,

215
00:11:47,525 --> 00:11:48,570
the one that we set here now,

216
00:11:48,570 --> 00:11:51,900
and so this one now happened a little bit later than before,

217
00:11:51,900 --> 00:11:54,470
because before, it was happening at 10%,

218
00:11:54,470 --> 00:11:56,490
but now only at 20%.

219
00:11:56,490 --> 00:11:57,683
So that's a bit later.

220
00:11:59,224 --> 00:12:01,173
Let's just clear this and keep scrolling,

221
00:12:02,140 --> 00:12:04,993
and so now this section is almost scrolling out of view,

222
00:12:06,533 --> 00:12:09,063
and you see, we now get this 20% here.

223
00:12:10,368 --> 00:12:14,070
So a bit less than 20%, and as we keep scrolling,

224
00:12:14,070 --> 00:12:18,690
then, then as this line hits here the top of the viewport,

225
00:12:18,690 --> 00:12:20,740
we should get another one, which is when

226
00:12:20,740 --> 00:12:23,503
this zero here is again reached.

227
00:12:24,853 --> 00:12:25,686
So let's try that.

228
00:12:26,658 --> 00:12:27,808
And indeed, here it is.

229
00:12:29,392 --> 00:12:31,410
So we are back to intersection ratio at zero,

230
00:12:31,410 --> 00:12:35,113
and the element is no longer visible, all right?

231
00:12:36,320 --> 00:12:40,600
So this is how the intersection observer API works,

232
00:12:40,600 --> 00:12:43,620
and let's now quickly use this in order to implement

233
00:12:43,620 --> 00:12:46,290
our sticky navigation, because at this point,

234
00:12:46,290 --> 00:12:48,920
I'm sure that you can already imagine

235
00:12:48,920 --> 00:12:52,360
how this can be very useful for implementing this

236
00:12:52,360 --> 00:12:53,353
in an easy way.

237
00:12:57,044 --> 00:12:58,394
So, let's think about this.

238
00:12:59,472 --> 00:13:01,943
When do we want our navigation to become sticky?

239
00:13:03,449 --> 00:13:05,520
Well, we want that to happen essentially

240
00:13:05,520 --> 00:13:08,453
when the header moves completely out of view.

241
00:13:09,722 --> 00:13:11,522
So basically, all of this part here,

242
00:13:12,426 --> 00:13:15,347
which is the header, when we can no longer see it,

243
00:13:15,347 --> 00:13:19,283
that's when we want then to display the navigation, okay?

244
00:13:20,450 --> 00:13:21,283
And so this time, we are going

245
00:13:21,283 --> 00:13:23,263
to observe the header element.

246
00:13:25,691 --> 00:13:27,113
So let's start by selecting that.

247
00:13:33,397 --> 00:13:37,923
And it is an element with the class of header, all right?

248
00:13:39,155 --> 00:13:41,883
Let's actually get rid of this part here.

249
00:13:45,273 --> 00:13:47,953
Okay, and now let's create our observer.

250
00:13:51,375 --> 00:13:53,725
So this time I'm calling it the headerObserver,

251
00:13:54,943 --> 00:13:57,293
just so we know exactly what is being observed.

252
00:13:58,219 --> 00:14:00,253
So new IntersectionObserver,

253
00:14:02,769 --> 00:14:04,600
and then I'm gonna pass in the arguments later,

254
00:14:04,600 --> 00:14:07,330
and then I will use the headerObserver

255
00:14:09,114 --> 00:14:12,173
to observe the header.

256
00:14:13,120 --> 00:14:13,953
Okay?

257
00:14:15,137 --> 00:14:18,210
So this all kind of sound like normal English sentences

258
00:14:18,210 --> 00:14:20,713
if we read it like this, right?

259
00:14:22,730 --> 00:14:25,560
So here we again need a callback function,

260
00:14:25,560 --> 00:14:27,260
so let's just call this stickyNav,

261
00:14:28,658 --> 00:14:30,790
actually, and then again the options.

262
00:14:30,790 --> 00:14:32,630
Now this time, I will just create

263
00:14:32,630 --> 00:14:36,703
the options object right here, all right?

264
00:14:39,704 --> 00:14:41,873
And so the root will once again be null,

265
00:14:43,401 --> 00:14:46,964
because we are again interested in the entire viewport,

266
00:14:46,964 --> 00:14:48,093
and then the threshold.

267
00:14:50,094 --> 00:14:52,360
So, I said that we are interested in showing

268
00:14:52,360 --> 00:14:55,200
the sticky navigation as soon as this header

269
00:14:55,200 --> 00:14:57,203
scrolls completely out of view.

270
00:14:58,448 --> 00:15:00,098
So what threshold does that mean?

271
00:15:01,470 --> 00:15:03,373
Well, that's just zero, right?

272
00:15:04,496 --> 00:15:08,200
So when 0% of the header here is visible,

273
00:15:08,200 --> 00:15:10,383
then we want something to happen.

274
00:15:14,340 --> 00:15:17,883
Okay, and now let's define this function here,

275
00:15:18,787 --> 00:15:21,420
and here we will have exactly the functionality

276
00:15:21,420 --> 00:15:24,850
that we want to happen, so to add and to remove

277
00:15:24,850 --> 00:15:26,033
the sticky class.

278
00:15:27,663 --> 00:15:29,830
So this function gets the entries, and this time,

279
00:15:29,830 --> 00:15:31,830
I'm not gonna specify the observer,

280
00:15:31,830 --> 00:15:33,913
because in this case, we don't need it.

281
00:15:36,048 --> 00:15:37,948
Also, there's only one threshold here,

282
00:15:38,964 --> 00:15:41,377
so I don't need to loop over the entries.

283
00:15:41,377 --> 00:15:42,703
We can simply get the first one,

284
00:15:44,256 --> 00:15:46,778
and let's actually use destructuring

285
00:15:46,778 --> 00:15:49,733
to get the first element, so entry,

286
00:15:51,006 --> 00:15:53,006
to get the first element out of entries.

287
00:15:54,930 --> 00:15:56,623
And remember that this is the same

288
00:15:56,623 --> 00:15:59,803
as writing entries zero, right?

289
00:16:02,688 --> 00:16:05,973
So, let's just start by taking a look at this entry,

290
00:16:07,045 --> 00:16:08,193
just to see if it works.

291
00:16:10,208 --> 00:16:12,820
And here, one more time, we already get something,

292
00:16:12,820 --> 00:16:15,460
so I'm not sure why that is actually,

293
00:16:15,460 --> 00:16:18,163
because this has nothing to do with our threshold.

294
00:16:19,910 --> 00:16:23,283
All right, but let's just wait for the next one,

295
00:16:24,255 --> 00:16:26,251
and so it should be appearing soon,

296
00:16:26,251 --> 00:16:28,970
because our target, so this header is almost moving

297
00:16:28,970 --> 00:16:33,183
out of the view, and indeed, here it is.

298
00:16:35,268 --> 00:16:36,830
So intersection ratio is zero,

299
00:16:36,830 --> 00:16:38,893
and it is no longer intersecting.

300
00:16:41,135 --> 00:16:43,690
And so now, let's actually create the logic

301
00:16:43,690 --> 00:16:46,083
of adding and removing the classes.

302
00:16:49,055 --> 00:16:51,830
So basically what we want to do

303
00:16:51,830 --> 00:16:55,393
is to first add it here, and so let's start with that.

304
00:17:00,414 --> 00:17:03,414
But you see that now it actually already applied this class,

305
00:17:04,933 --> 00:17:06,470
and that's because right now, our target element

306
00:17:06,470 --> 00:17:10,400
is intersecting the root, so the viewport, all right?

307
00:17:10,400 --> 00:17:12,163
So we will use that in a second.

308
00:17:13,565 --> 00:17:15,233
Let's just see what happens next.

309
00:17:17,222 --> 00:17:20,713
So here we will now get our next one, right?

310
00:17:22,023 --> 00:17:24,170
And so now it is no longer intersecting.

311
00:17:24,170 --> 00:17:27,683
So intersection ratio zero, but no longer intersecting.

312
00:17:28,867 --> 00:17:29,750
And so this is actually the condition

313
00:17:29,750 --> 00:17:32,550
that we are interested in, right?

314
00:17:32,550 --> 00:17:36,220
So only when the header is not intersecting the viewport

315
00:17:36,220 --> 00:17:39,020
is when we want to add that sticky class,

316
00:17:39,020 --> 00:17:42,683
because watch what happens when we move back up.

317
00:17:46,289 --> 00:17:51,090
So right now, you see we got this new entry here,

318
00:17:53,370 --> 00:17:57,473
and so in this case, it is again intersecting,

319
00:17:58,584 --> 00:18:01,310
and so, and in this case where we are scrolling up

320
00:18:01,310 --> 00:18:05,570
is when we actually want to remove that sticky class, right?

321
00:18:05,570 --> 00:18:07,350
So we are entering the header again,

322
00:18:07,350 --> 00:18:09,190
and so that's the point in time

323
00:18:09,190 --> 00:18:12,603
where we want the sticky class to be gone.

324
00:18:14,064 --> 00:18:16,550
And so now we can use this intersecting property

325
00:18:16,550 --> 00:18:17,913
to do exactly that.

326
00:18:19,931 --> 00:18:24,931
So we can say that if the entry.isIntersecting is false,

327
00:18:30,115 --> 00:18:31,393
basically, then do this.

328
00:18:33,578 --> 00:18:34,411
Right?

329
00:18:34,411 --> 00:18:38,670
So again, when the target is not intersecting the root,

330
00:18:38,670 --> 00:18:41,553
then we want the sticky class to be applied.

331
00:18:42,860 --> 00:18:45,553
And else, we want to remove it.

332
00:18:53,031 --> 00:18:53,864
So let's reload,

333
00:18:56,346 --> 00:18:59,403
and now indeed, the sticky class is no longer there, okay?

334
00:19:02,033 --> 00:19:04,040
And now watch what happens as this line

335
00:19:04,040 --> 00:19:08,423
reaches the top there, then yeah, here it is.

336
00:19:09,684 --> 00:19:11,240
So there is our sticky navigation,

337
00:19:11,240 --> 00:19:14,308
so that's great, and indeed, it is because

338
00:19:14,308 --> 00:19:16,653
it is now no longer intersecting.

339
00:19:18,393 --> 00:19:20,800
And so now the final test is when we move back up,

340
00:19:20,800 --> 00:19:25,120
then it is gone, and so as we scroll around this point,

341
00:19:25,120 --> 00:19:27,810
it will basically add and remove the class

342
00:19:27,810 --> 00:19:29,883
according to the scrolling direction.

343
00:19:31,444 --> 00:19:33,910
Now we're actually not really done yet

344
00:19:33,910 --> 00:19:35,890
because I want to make this a little bit different,

345
00:19:35,890 --> 00:19:36,913
or a bit better.

346
00:19:38,105 --> 00:19:39,303
So let me show you the demo here,

347
00:19:40,784 --> 00:19:42,833
so just to make sure, I'm gonna reload it here,

348
00:19:45,000 --> 00:19:47,193
never mind this effect you just saw here.

349
00:19:48,345 --> 00:19:50,545
But watch when the navigation comes in here.

350
00:19:53,959 --> 00:19:55,710
So you see when that happens, it's basically

351
00:19:55,710 --> 00:19:58,370
when the distance between the start of the section

352
00:19:58,370 --> 00:20:01,210
and the viewport here is just the same

353
00:20:01,210 --> 00:20:02,900
as the navigation.

354
00:20:02,900 --> 00:20:04,100
You see that?

355
00:20:04,100 --> 00:20:07,283
And so like this, the navigation doesn't overlap

356
00:20:07,283 --> 00:20:09,483
this section here right in the beginning.

357
00:20:11,657 --> 00:20:14,180
So here the navigation comes exactly before

358
00:20:14,180 --> 00:20:16,043
the first section starts.

359
00:20:17,362 --> 00:20:18,890
And so let's implement it here as well

360
00:20:18,890 --> 00:20:22,120
and thankfully, that's pretty easy to do,

361
00:20:22,120 --> 00:20:26,440
and we can do it by specifying another property here

362
00:20:26,440 --> 00:20:30,850
which is the rootMargin, okay?

363
00:20:30,850 --> 00:20:34,490
And this root margin here, for example 90,

364
00:20:34,490 --> 00:20:37,890
is a box of 90 pixels that will be applied

365
00:20:37,890 --> 00:20:40,373
outside of our target element,

366
00:20:41,588 --> 00:20:43,600
so of our header here, okay?

367
00:20:43,600 --> 00:20:45,909
And so now it is as if the header

368
00:20:45,909 --> 00:20:50,563
did not stop right here, but instead, out here.

369
00:20:51,630 --> 00:20:53,202
All right?

370
00:20:53,202 --> 00:20:55,880
So as if the header went all the way here.

371
00:20:55,880 --> 00:21:00,800
Now we actually want the header to basically stop here.

372
00:21:00,800 --> 00:21:02,473
And so that's -90.

373
00:21:04,300 --> 00:21:08,200
Okay, and here we then need to specify also the unit,

374
00:21:08,200 --> 00:21:11,600
which has got to be pixels, so unfortunately,

375
00:21:11,600 --> 00:21:15,940
percentage does not work, and also rem does not work

376
00:21:15,940 --> 00:21:18,340
so it has to be pixels, and so that's why

377
00:21:18,340 --> 00:21:20,330
I'm using 90 pixels here.

378
00:21:20,330 --> 00:21:23,113
And 90 is the height of the navigation,

379
00:21:24,310 --> 00:21:26,493
and so let's test this here again.

380
00:21:28,034 --> 00:21:31,483
So let's see, and so let's wait for it,

381
00:21:32,370 --> 00:21:33,810
and did you see that?

382
00:21:33,810 --> 00:21:38,240
Indeed, now the navigation appeared exactly 90 pixels

383
00:21:38,240 --> 00:21:40,933
before the threshold was actually reached.

384
00:21:42,359 --> 00:21:45,453
So you see, now we get the event here even later,

385
00:21:46,310 --> 00:21:48,483
and all the data here is still the same.

386
00:21:49,540 --> 00:21:51,990
This is simply a visual margin that gets applied.

387
00:21:53,429 --> 00:21:54,810
So you can play around with this as well

388
00:21:54,810 --> 00:21:57,400
with the difference between a positive

389
00:21:57,400 --> 00:22:01,920
and a negative margin to figure out really how this works,

390
00:22:01,920 --> 00:22:04,660
because this root margin here is very important

391
00:22:04,660 --> 00:22:08,393
to specify correctly, as we need it in many situations.

392
00:22:09,845 --> 00:22:12,320
Now just as one final detail, let's actually calculate

393
00:22:12,320 --> 00:22:14,083
this height here dynamically.

394
00:22:15,020 --> 00:22:19,423
And for that, we can use the getBoundingClientRect function,

395
00:22:21,980 --> 00:22:25,293
because for example if you have a responsive site,

396
00:22:26,548 --> 00:22:29,322
then probably the size of all your elements

397
00:22:29,322 --> 00:22:33,152
will change at certain points, and then it's not a good idea

398
00:22:33,152 --> 00:22:37,000
to have this 90 pixels here hard coded

399
00:22:37,000 --> 00:22:38,200
right there in the code.

400
00:22:39,485 --> 00:22:40,500
Let's just take a look so we see

401
00:22:40,500 --> 00:22:42,333
what we actually need to get.

402
00:22:45,387 --> 00:22:48,576
So this is the rectangle, and so here we actually

403
00:22:48,576 --> 00:22:49,726
have a height property.

404
00:22:50,788 --> 00:22:52,503
So this is where that 90 comes from.

405
00:22:54,680 --> 00:22:57,193
So let's read that directly here, height.

406
00:22:58,720 --> 00:23:00,923
All right, and so now here we can use that.

407
00:23:04,260 --> 00:23:05,653
Let's create a nice template string here,

408
00:23:09,944 --> 00:23:14,611
navHeight, and with that, I believe we're actually done.

409
00:23:16,625 --> 00:23:17,870
All right, and of course this works

410
00:23:17,870 --> 00:23:21,803
no matter how large or how small the viewport is.

411
00:23:27,587 --> 00:23:29,680
Okay, now it works beautifully and correctly

412
00:23:29,680 --> 00:23:33,040
in all situations and this is a lot more performant

413
00:23:33,040 --> 00:23:35,770
and a lot better than the solution that I showed you

414
00:23:35,770 --> 00:23:37,023
in the previous lecture.

415
00:23:38,216 --> 00:23:39,780
So play around with this but we will actually

416
00:23:39,780 --> 00:23:42,680
also have I think two more examples

417
00:23:42,680 --> 00:23:46,260
with the intersection observer API coming up

418
00:23:46,260 --> 00:23:48,620
and so that's gonna be another great opportunity

419
00:23:48,620 --> 00:23:51,580
to learn how this API really works,

420
00:23:51,580 --> 00:23:54,300
because it's quite important actually to do things

421
00:23:54,300 --> 00:23:57,204
on certain positions on the page,

422
00:23:57,204 --> 00:23:58,754
so things related to scrolling.

