All language subtitles for 16. A Better Way The Intersection Observer API

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

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.