Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
All right. 2
2
So let's now implement the same sticky navigation 3
3
that we implemented in the last video, 4
4
but this time, using the new intersection observer API. 5
5
But what actually is the intersection observer API, 6
6
and why is it so helpful? 7
7
Well, this API allows our code to basically 8
8
observe changes to the way that a certain target element 9
9
intersects another element, or the way 10
10
it intersects the viewport. 11
11
And so from this definition alone, 12
12
I think you can see that this will actually 13
13
be useful in implementing our sticky navigation. 14
14
But let's actually start this video by learning 15
15
how the intersection observer API actually works, 16
16
but without our sticky navigation, 17
17
because at the beginning, this can seem 18
18
a bit intimidating and confusing, okay? 19
19
So to use the intersection observer API, 20
20
we need to start by creating a new intersection observer. 21
21
So that's IntersectionObserver, just like this, 22
22
and then here, we will have to pass in a callback function 23
23
and an object of options. 24
24
But let's leave that for a bit later, okay? 25
25
So let's first store the result of calling this function 26
26
into a new variable. 27
27
So let's simply call it the observer, 28
28
and so now, we have to use this observer 29
29
to basically observe a certain target. 30
30
So observer and then the method we call on that is observe. 31
31
And then here, the target element. 32
32
And this one will be section one, 33
33
and so this is an element that we already selected before. 34
34
So this will make a bit more sense 35
35
once we actually create the callback and the options here, 36
36
and let's start by the options. 37
37
So const, let's call it the observer options, 38
38
so obsOptions, 39
39
so this is gonna be an object, 40
40
and we can also already create the callback function. 41
41
Let's simply call this observerCallback. 42
42
All right, and of course, we could've created 43
43
these right here, because this is where we will now 44
44
pass them in, so first the callback, 45
45
and second the options, okay? 46
46
And so once again, we could've written the function 47
47
and the object directly in here, 48
48
but I think it's a bit cleaner to have them separately. 49
49
So let's now start with the options here, 50
50
and so this object needs first a root property. 51
51
And this root is the element 52
52
that the target is intersecting. 53
53
So again, this here is the target, 54
54
and the root element will be the element 55
55
that we want our target element to intersect. 56
56
And again, this will all make more sense 57
57
once you see this in action. 58
58
So we could now here select an element 59
59
or as an alternative, we can write null, 60
60
and then we will be able to observe our target element 61
61
intersecting the entire viewport, all right?. 62
62
So basically, this entire rectangle here, 63
63
which shows the current portion of the page, okay? 64
64
And then second, we can define a threshold. 65
65
Threshold, and this is basically the percentage 66
66
of intersection at which 67
67
the observer callback will be called, 68
68
so this callback here. 69
69
So again that's very confusing, 70
70
let's just set it to 10%, which is 0.1, 71
71
and then when we have this callback function here 72
72
also created, then we will see what actually 73
73
happens here in practice. 74
74
All right. 75
75
So this callback function here will get called 76
76
each time that the observed element, 77
77
so our target element here, is intersecting 78
78
the root element at the threshold that we defined, okay? 79
79
So take note of this because this is actually 80
80
a bit hard to figure out from reading the documentation. 81
81
And so it's a good idea to keep note 82
82
of what I'm saying here. 83
83
So in the current example, whenever the first section, 84
84
so our target here, is intersecting the viewport at 10%, 85
85
so the viewport, because that's the root, 86
86
and 10% because that's the threshold. 87
87
So whenever that happens, then this function here 88
88
will get called and that's no matter if we are scrolling 89
89
up or down, all right? 90
90
And this function will get called with two arguments, 91
91
and so we can specify them here, 92
92
and that's the entries and the observer object itself. 93
93
All right, so this object here basically 94
94
will also get passed into the callback function, all right? 95
95
Now this case, we're only interested in the entries, 96
96
but sometimes using the observer is also useful. 97
97
Now we can have actually multiple thresholds, 98
98
so here we can have an array, and I will do that 99
99
in a minute, and so these entries here 100
100
are actually an array of the threshold entries, okay, 101
101
and so in this case again, there's only one element there, 102
102
but let's create a more general function already 103
103
which basically loops over these entries 104
104
so that we can take a look at all of them. 105
105
And so let's just do that, so basically, 106
106
simply log them to the console, 107
107
and that will already be good enough for us 108
108
to take a look at how this all works. 109
109
So entry, and so you see I'm using an arrow function here, 110
110
but of course any other function would work just the same. 111
111
Let's give it a save now, and you see that already, 112
112
we get an intersection observer entry, 113
113
and so that is this entry here. 114
114
And so this is not really interesting yet, 115
115
because this is just the first one that we got 116
116
and we see that the ratio here is at zero, 117
117
but let's see in a second what that actually means. 118
118
So I will start scrolling here, and you see 119
119
that now we actually got our first real entry here, 120
120
which appeared here because our target element 121
121
came into the viewport. 122
122
So our target element is this whole h1 123
123
that's down here, and so you see that it started 124
124
intersecting the viewport, okay? 125
125
And so our observer is observing that, 126
126
and so now here you see that the intersection ratio 127
127
at the time that this callback here was called, 128
128
so this one here, was at 0.10, and then this. 129
129
And so that's exactly the 10% threshold 130
130
that we defined over here, all right? 131
131
We also get this isIntersecting property, 132
132
which in this case is true, and that is because indeed, 133
133
our target, so again this whole section here, 134
134
is now intersecting the viewport. 135
135
And we are looking for the viewport, remember, 136
136
because we set the root to null. 137
137
All right? 138
138
So we also get the target itself here, 139
139
and a couple of other stuff, 140
140
but the intersection ratio is actually 141
141
the most interesting one and also the isIntersecting here. 142
142
Okay, so let's scroll down a little bit more, 143
143
and let's close this actually, 144
144
and let's scroll up again, and so again, 145
145
we get a new entry here, and so again, 146
146
it should be close to 10%, 147
147
but now it happened as we were moving up, right? 148
148
And so again it was at 10%, but now, 149
149
it is no longer intersecting, okay? 150
150
And it's not intersecting because the threshold is at 10. 151
151
And so now less than 10% basically of our target here 152
152
are inside of the root, so inside of the viewport. 153
153
All right, and so you can start to see 154
154
why this is more efficient. 155
155
So it's because we only get this kind of event here 156
156
in the situation that we're actually interested in. 157
157
So in this case, that's this threshold of 10%. 158
158
Okay, and as we keep scrolling here, 159
159
now it will come back again, 160
160
and now it is again intersecting, 161
161
let's keep scrolling, and all of this here is section one, 162
162
and now we got another one. 163
163
So let's see, and so now it is back to not intersecting, 164
164
because now we no longer have 10% visible, okay? 165
165
So you can think of this threshold here 166
166
at the percentage that we want to have visible in our root. 167
167
So in our viewport in this case, and so, 168
168
right now we are back to having less than 10%, 169
169
and so it is no longer intersecting here. 170
170
And again, if we scroll up a little bit more, 171
171
then we get another event here because now 172
172
we are back to having 10% intersection ratio, okay? 173
173
So this is the very fundamentals of how 174
174
the intersection observer API works, 175
175
and I confess that it is a bit confusing 176
176
and it took me quite some time to figure all of this out, 177
177
and so probably the best idea is for you 178
178
to stop this video now and explore this 179
179
a little bit on your own. 180
180
So you can use different threshold values, 181
181
and maybe use different targets here, 182
182
you can even use different roots, 183
183
and so it would be a good idea to experiment 184
184
a little bit more with this. 185
185
Now what I'm gonna do here is to now specify an array, 186
186
so to specify different thresholds, 187
187
and one of them is gonna be zero, 188
188
and the other one 0.2, so that's 20%. 189
189
So 0% here means that basically our callback 190
190
will trigger each time that the target element 191
191
moves completely out of the view, 192
192
and also as soon as it enters the view, okay? 193
193
And so that's because the callback function 194
194
will be called when the threshold is passed 195
195
when moving into the view and when moving out of the view, 196
196
and this is really important to remember here. 197
197
On the other hand, if we specified one here, 198
198
like this, then that means that the callback 199
199
will only be called when 100% of the target 200
200
is actually visible in the viewport. 201
201
So in the case of this section one, 202
202
that would be impossible because the section itself 203
203
is already bigger than the viewport. 204
204
But let's now experiment with zero here, 205
205
and so right away, we again get this event here, 206
206
and you see that the intersection ratio 207
207
is exactly at zero, but it is already intersecting, 208
208
and so it's because basically the threshold here 209
209
was already passed. 210
210
All right? 211
211
So I think another one happened there, 212
212
let's just reload, oh, and that was probably 213
213
from our 20%. 214
214
Yep, so you see, this is the 20 threshold, 215
215
the one that we set here now, 216
216
and so this one now happened a little bit later than before, 217
217
because before, it was happening at 10%, 218
218
but now only at 20%. 219
219
So that's a bit later. 220
220
Let's just clear this and keep scrolling, 221
221
and so now this section is almost scrolling out of view, 222
222
and you see, we now get this 20% here. 223
223
So a bit less than 20%, and as we keep scrolling, 224
224
then, then as this line hits here the top of the viewport, 225
225
we should get another one, which is when 226
226
this zero here is again reached. 227
227
So let's try that. 228
228
And indeed, here it is. 229
229
So we are back to intersection ratio at zero, 230
230
and the element is no longer visible, all right? 231
231
So this is how the intersection observer API works, 232
232
and let's now quickly use this in order to implement 233
233
our sticky navigation, because at this point, 234
234
I'm sure that you can already imagine 235
235
how this can be very useful for implementing this 236
236
in an easy way. 237
237
So, let's think about this. 238
238
When do we want our navigation to become sticky? 239
239
Well, we want that to happen essentially 240
240
when the header moves completely out of view. 241
241
So basically, all of this part here, 242
242
which is the header, when we can no longer see it, 243
243
that's when we want then to display the navigation, okay? 244
244
And so this time, we are going 245
245
to observe the header element. 246
246
So let's start by selecting that. 247
247
And it is an element with the class of header, all right? 248
248
Let's actually get rid of this part here. 249
249
Okay, and now let's create our observer. 250
250
So this time I'm calling it the headerObserver, 251
251
just so we know exactly what is being observed. 252
252
So new IntersectionObserver, 253
253
and then I'm gonna pass in the arguments later, 254
254
and then I will use the headerObserver 255
255
to observe the header. 256
256
Okay? 257
257
So this all kind of sound like normal English sentences 258
258
if we read it like this, right? 259
259
So here we again need a callback function, 260
260
so let's just call this stickyNav, 261
261
actually, and then again the options. 262
262
Now this time, I will just create 263
263
the options object right here, all right? 264
264
And so the root will once again be null, 265
265
because we are again interested in the entire viewport, 266
266
and then the threshold. 267
267
So, I said that we are interested in showing 268
268
the sticky navigation as soon as this header 269
269
scrolls completely out of view. 270
270
So what threshold does that mean? 271
271
Well, that's just zero, right? 272
272
So when 0% of the header here is visible, 273
273
then we want something to happen. 274
274
Okay, and now let's define this function here, 275
275
and here we will have exactly the functionality 276
276
that we want to happen, so to add and to remove 277
277
the sticky class. 278
278
So this function gets the entries, and this time, 279
279
I'm not gonna specify the observer, 280
280
because in this case, we don't need it. 281
281
Also, there's only one threshold here, 282
282
so I don't need to loop over the entries. 283
283
We can simply get the first one, 284
284
and let's actually use destructuring 285
285
to get the first element, so entry, 286
286
to get the first element out of entries. 287
287
And remember that this is the same 288
288
as writing entries zero, right? 289
289
So, let's just start by taking a look at this entry, 290
290
just to see if it works. 291
291
And here, one more time, we already get something, 292
292
so I'm not sure why that is actually, 293
293
because this has nothing to do with our threshold. 294
294
All right, but let's just wait for the next one, 295
295
and so it should be appearing soon, 296
296
because our target, so this header is almost moving 297
297
out of the view, and indeed, here it is. 298
298
So intersection ratio is zero, 299
299
and it is no longer intersecting. 300
300
And so now, let's actually create the logic 301
301
of adding and removing the classes. 302
302
So basically what we want to do 303
303
is to first add it here, and so let's start with that. 304
304
But you see that now it actually already applied this class, 305
305
and that's because right now, our target element 306
306
is intersecting the root, so the viewport, all right? 307
307
So we will use that in a second. 308
308
Let's just see what happens next. 309
309
So here we will now get our next one, right? 310
310
And so now it is no longer intersecting. 311
311
So intersection ratio zero, but no longer intersecting. 312
312
And so this is actually the condition 313
313
that we are interested in, right? 314
314
So only when the header is not intersecting the viewport 315
315
is when we want to add that sticky class, 316
316
because watch what happens when we move back up. 317
317
So right now, you see we got this new entry here, 318
318
and so in this case, it is again intersecting, 319
319
and so, and in this case where we are scrolling up 320
320
is when we actually want to remove that sticky class, right? 321
321
So we are entering the header again, 322
322
and so that's the point in time 323
323
where we want the sticky class to be gone. 324
324
And so now we can use this intersecting property 325
325
to do exactly that. 326
326
So we can say that if the entry.isIntersecting is false, 327
327
basically, then do this. 328
328
Right? 329
329
So again, when the target is not intersecting the root, 330
330
then we want the sticky class to be applied. 331
331
And else, we want to remove it. 332
332
So let's reload, 333
333
and now indeed, the sticky class is no longer there, okay? 334
334
And now watch what happens as this line 335
335
reaches the top there, then yeah, here it is. 336
336
So there is our sticky navigation, 337
337
so that's great, and indeed, it is because 338
338
it is now no longer intersecting. 339
339
And so now the final test is when we move back up, 340
340
then it is gone, and so as we scroll around this point, 341
341
it will basically add and remove the class 342
342
according to the scrolling direction. 343
343
Now we're actually not really done yet 344
344
because I want to make this a little bit different, 345
345
or a bit better. 346
346
So let me show you the demo here, 347
347
so just to make sure, I'm gonna reload it here, 348
348
never mind this effect you just saw here. 349
349
But watch when the navigation comes in here. 350
350
So you see when that happens, it's basically 351
351
when the distance between the start of the section 352
352
and the viewport here is just the same 353
353
as the navigation. 354
354
You see that? 355
355
And so like this, the navigation doesn't overlap 356
356
this section here right in the beginning. 357
357
So here the navigation comes exactly before 358
358
the first section starts. 359
359
And so let's implement it here as well 360
360
and thankfully, that's pretty easy to do, 361
361
and we can do it by specifying another property here 362
362
which is the rootMargin, okay? 363
363
And this root margin here, for example 90, 364
364
is a box of 90 pixels that will be applied 365
365
outside of our target element, 366
366
so of our header here, okay? 367
367
And so now it is as if the header 368
368
did not stop right here, but instead, out here. 369
369
All right? 370
370
So as if the header went all the way here. 371
371
Now we actually want the header to basically stop here. 372
372
And so that's -90. 373
373
Okay, and here we then need to specify also the unit, 374
374
which has got to be pixels, so unfortunately, 375
375
percentage does not work, and also rem does not work 376
376
so it has to be pixels, and so that's why 377
377
I'm using 90 pixels here. 378
378
And 90 is the height of the navigation, 379
379
and so let's test this here again. 380
380
So let's see, and so let's wait for it, 381
381
and did you see that? 382
382
Indeed, now the navigation appeared exactly 90 pixels 383
383
before the threshold was actually reached. 384
384
So you see, now we get the event here even later, 385
385
and all the data here is still the same. 386
386
This is simply a visual margin that gets applied. 387
387
So you can play around with this as well 388
388
with the difference between a positive 389
389
and a negative margin to figure out really how this works, 390
390
because this root margin here is very important 391
391
to specify correctly, as we need it in many situations. 392
392
Now just as one final detail, let's actually calculate 393
393
this height here dynamically. 394
394
And for that, we can use the getBoundingClientRect function, 395
395
because for example if you have a responsive site, 396
396
then probably the size of all your elements 397
397
will change at certain points, and then it's not a good idea 398
398
to have this 90 pixels here hard coded 399
399
right there in the code. 400
400
Let's just take a look so we see 401
401
what we actually need to get. 402
402
So this is the rectangle, and so here we actually 403
403
have a height property. 404
404
So this is where that 90 comes from. 405
405
So let's read that directly here, height. 406
406
All right, and so now here we can use that. 407
407
Let's create a nice template string here, 408
408
navHeight, and with that, I believe we're actually done. 409
409
All right, and of course this works 410
410
no matter how large or how small the viewport is. 411
411
Okay, now it works beautifully and correctly 412
412
in all situations and this is a lot more performant 413
413
and a lot better than the solution that I showed you 414
414
in the previous lecture. 415
415
So play around with this but we will actually 416
416
also have I think two more examples 417
417
with the intersection observer API coming up 418
418
and so that's gonna be another great opportunity 419
419
to learn how this API really works, 420
420
because it's quite important actually to do things 421
421
on certain positions on the page, 422
422
so things related to scrolling.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.