Learn Intersection Observer In 15 Minutes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you want to do fancy scroll based animations lazy load images or implement infinite scrolling then you're going to need intersection observer and in this video i'm going to teach you everything you need to know about intersection observer [Music] welcome back to web dev simplified my name is kyle and my job is to simplify the web for you in this video i'm covering everything you need to know about intersection observer and on the right-hand side you see the finished version of what we're going to create we're going to take essentially this html that has a bunch of cards inside of a container you can see we have a first card and a last card and we're going to implement this really cool animation where they kind of come in from the right hand side of the screen and leave at the top hand side of the screen and then once we get to the final card you'll see this is our final card we're going to infinitely scroll by constantly adding new cards to our html so no matter how far we scroll we're just always adding new cards over and over and over again so using intersection observer we're going to implement both of these and figure out how intersection works along the way so starting we just have this blank html page and that's because by default all these cards are hidden if i go to my script i'm sorry my style is here you can see that the cards have a show class we need to add to them and that's going to give us our animation so if i come over to my html and i add a show class to this first card you can see it shows up here while without that class it's going to be completely hidden so the show class is going to be how we give it the animation because as soon as our thing scrolls onto the page we want to add the show class so in order to handle scrolling if we go into our script js most of the time what you'll see is someone will do like a set interval and in that center interval they're just going to constantly check is this thing on the page that's not very performant because it's just constantly going to be doing work in the background and it's not always going to be super accurate so instead what you want to do is use an intersection observer so we can create a variable here called observer and we're going to create a new intersection observer and an intersection observer takes in a callback and it's going to take in some options for how you want to configure it the most important part though is going to be that callback because that callback is what gets called every single time something you're observing changes its intersection so this callback takes in essentially a list of entries and these entries are all the things that have changed the things that have intersected or unintersected so let's just come in here and we're just going to do a really simple console.log of our entries and our observer we need to tell it what we want it to observe so in our case let's just come in here and what i want to do is i want to get all of the cards so our cards are just going to be equal to document.queryselectorall for everything that has a card class and that's because in our html all of our cards have that card class and let's just make our first card visible because that's the one we're going to observe so to do an observe all we do is we take our observer and we call the observed method and what this does is it says hey what i want you to do is observe when this thing changes intersections so we're just going to put in our cards of zero that's our very first card so now if i inspect our page we should hopefully have something console logged out so let me just click inspect here go over to our console and you can see we have an array and that's important this entries that we get passed in is always going to be an array and it's a ray of everything that we're observing that has changed its observation essentially if it's intersecting or not within that period of time so if we open this up you can see our first element is the only one in here that's because we only are observing one thing and you'll see a bunch of information and i'll point out the most important things for you number one here we have our intersection ratio that's like what percentage of the object is on the screen in our case 100 of this thing is on the screen so that's why it says one is intersecting this is going to be true if our thing is intersecting and by intersecting by default what that means is is it on the screen is it visible to the user this is visible property don't worry about it it's like an experimental feature that doesn't really do much right now but important things here we have our bounding client rect that's the actual shape of the element that we're expecting here so our target here this first card this is just the rectangle that defines like the top bottom height and so on our intersecting rick this one is going to be the amount of space that is visible on the screen of the thing that we're actually targeting so this right now since 100 of our thing is on the screen this is just the same as our bounding client rect but if only 50 percent of our thing was visible on the screen this wrecked right here would show you the 50 of the thing that's on the screen finally we have our root bounds this is the bounds of our screen because our root is our screen by default and then finally we have our target down here and this is the actual thing that we're observing the most important properties that you're going to get from here is going to be is intersecting to see if it's on the screen or not and target to figure out what thing they're actually targeting so really simply what we can do inside of this function is we can add the show class if the thing is intersecting and we can remove the show class as soon as it goes off the screen so we can just say entries dot four each entry what i want to do is i want to add the show class if it's visible and remove it if it's not so i can take our entry i can get the target which is the actual thing that we're looking at i get the class list and i can toggle a class which in our place is show and then i can just take our entry dot is intersecting so if we are intersecting that'll be true which means we add the show class and if this is not intersecting it'll be false which means we remove that show class and now what i can do is i can come in here i can get rid of that show class from our card and down here i'm going to just loop through all of our cards so cards.for each card what i want to do is i want to observe that card so we're going to say observe of the card and what this does is it's observing every single card in our list and that's because observe only takes one element at a time which is why we're doing this loop here so now if i save you can see all of these cards animate into the screen because they're all visible on the screen and as i start scrolling you'll notice something interesting we don't really see that animation for the card if i scroll fast enough you'll be able to see it but you'll notice it doesn't actually animate on screen it's animating off screen and that's because by default the way intersection observer works is that as soon as a single pixel of the element is visible so as soon as the bottom border here is visible on the screen it's going to say that it's visible the is intersecting property here is going to be set to true what we want to do is only set this to true as soon as our entire element is visible on the screen that we can actually observe the animation and that's where the second property to this intersection observer is really useful this is an options argument and this takes in a threshold this threshold is a value between zero and one and it represents a percentage by default the percentage is zero so as soon as the element is just about to be visible on the screen then it's going to be considered intersecting well if we put one that means 100 of the element must be on the screen before the animation plays or before this function gets called now if we scroll down you'll notice as soon as our element at the very top starts to go off the page now the threshold is not 100 because less than 100 of it is visible so we call this function is intersecting as false because it is now no longer on the page and it plays the animation down here as soon as the entirety of this card down here is on the screen then it's going to call this function and say is intersecting as true we change threshold to like 0.5 for example now as soon as 50 of the element is disappearing or showing up then the animation is going to play so if we look at the bottom you can see as soon as 50 of the card is visible then it goes in and up here as soon as 50 of it becomes unvisible then it's going to disappear so this threshold can be really good in our case with the animation we want to set this to one that makes the most sense because it's going to give us a really good looking animation as we scroll up and down you can see everything is animating in and out it looks really good now one important thing to know is you have these fancy animations where things like fade into the page i know if you've been on popular websites as you're scrolling down a lot of the content of the site like builds itself in cool animations but then when you scroll back up to it it doesn't rebuild itself it just stays there one easy way to do that with intersection observer is every single time that we add an element to the page by doing this show thing by making it visible all we want to do is just stop observing it so what we can do is we can say entry i'm sorry if entry dot is intersecting so if it is visible on the screen i want to take our observer and i want to stop observing this so we can say unobserve the entry dot target now if i save you'll notice on the interesting these animate in and as i scroll down they don't animate away they just stay there the bottom ones still animate in and then if i scroll up you'll notice there's no more animations and that's because as soon as they become visible on the page we're removing them from our observer so they no longer call this function anymore and then once everything's visible there's nothing else being observed by our observer so this is a really great way to only do something as soon as something is visible and then don't do anything else so if you're lazy loading images for example as soon as the image is about to be shown on the page you'll want to run some code that downloads the image and then just stop observing that image because you don't care about it anymore and it's great in this case where we have animations that we want to play only as soon as the thing comes on page but then doesn't play anymore after that for now i think it looks better when they kind of come in and out so we'll just leave it as is for now because i kind of like this effect and we'll remove that line now another important property we can talk about down here besides just the threshold is going to be a property called root margin now the root margin is interesting because this allows us to essentially offset when something will happen so we put our threshold back to zero by default and we set our root margin here to like negative 50 pixels actually let's set it to negative 100 pixels and we save you're going to notice something interesting all of these elements up here are not visible and all the elements down here are not visible and the reason for that is because this root margin when we set it to negative 100 pixels it's saying that our container is now 100 pixels smaller than it normally would be so from the top of our container we're essentially subtracting 100 pixels so now everything that's going to be leaving that container is leaving it 100 pixels earlier and down here everything is coming in 100 pixels earlier because it's 100 pixels from the bottom of the screen so using negative numbers we can kind of shrink our container and make things do whatever we want before they actually leave or before they enter so here this is happening after it enters and up here before it leaves is when it's actually doing the animation well if we change this to a positive number such as positive 100 pixels now what happens is all the animations are playing when the element is 100 pixels away from becoming on the screen so now if we just inspect our page here and we go over to our elements tab we can kind of see what's happening by looking at the class list here way down here we have our last card right here if i scroll it all the way off our page notice it still has the show class i need to scroll it 100 pixels off the page then once it's 100 pixels off the page now the show class disappears so using this root margin is really useful if you want to you know pre-load images because you can say hey when my image is 250 pixels away from being shown then start loading it that way by the time people scroll to that image it's hopefully entirely loaded now the last type of property that i want to talk about that you can pass into options is going to be a property called root and root is where you can define the actual container that you care about in our case we're just using the actual body our whole document as the container so when it leaves the screen or joins the screen that's when it's going to be called but we can set the route to literally anything we want and as long as in your html you set the root to some parent element it attracts all of the children elements inside of it so if we made the card container our parent anytime a card left that card container parent it would actually do the thing and if we made card containers scrolling essentially we have to make sure the parent container is scrolling otherwise the container is going to be the same size as all the children but if we put scrolling on the card container and now we're like scrolling our card container which was nested in our page somewhere we could do the same exact thing so if we have a scrolling container we can set the root to that scrolling container and then when they leave or are shown on that scrolling container that's what the route is for 99 of the time you're not going to use this though because the actual route you want to be is the entire screen itself now in order to go back to what we had before i'm just going to change the threshold here back to one so we have our nice little loading animations and they look really good exactly like we want now the next thing i want to talk about is how we can actually implement lazy loading now what we could do is we could do all of this inside of one observer but this observer is really caring only about adding and removing the classes for actually showing the elements and this lazy loader is entirely different so i'm going to create a brand new intersection observer for this so i'm going to call this one the last card observer oops observer there we go i'm going to set it to a new intersection observer it's going to take a function that takes in all these entries and also it's going to take in some options now for our function what i want to do is essentially i want to get just the first element in our list so i can say last card is equal to our entries of zero and the reason that i'm doing that is because we're only going to observe one thing with this intersection observer and we're going to be observing our last card so i can say lastcardobserver.observe and i just want to get the last card so we can say document.queryselector of our dot card that is the last child so this is just going to get the very last card and we're going to observe just that one single thing so that's why we can just say hey get to the first element in this array because we're only observing one thing ever then what i want to do is i want to say hey if our last card is not intersecting then we're just going to return because the only thing we care about is when our last card starts to become visible then load in a bunch of new cards after that so then what we want to do is call some function after this so we'll say like load new cards and this function is only going to be called if our last card is visible and this function here i'm actually just going to copy over because the contents are not very important but essentially inside here imagine we're doing like a fetch to an api in our case we're just looping and creating 10 brand new cards we're putting the text content new card inside of them adding the class list we're making sure that we observe them so that they can do the animation so our main observer up here is observing the new cards we're creating and then we're just adding them to our card container pretty straightforward function so we're just loading a bunch of new cards as soon as we intersect with our last card and then a really important thing is we make sure that we unobserve our last card because we just observed it now we don't want to observe it anymore so we're going to say we're going to unobserve our last card which is just our last card dot target now the reason this is really important is because if you don't do this then now our intersection observer here is still going to be observing our last card but our last card is no longer the last card because now we have a new last card that we just added so what we want to do is we want to take our last card observer and we now want to observe a new card and this new card is just going to be our last card so we're just going to get a brand new last card here since we added 10 new cards this is going to get the new last card at the very bottom and here we're removing the old one so now if i save and i start scrolling down as soon as our last card becomes visible it should add new cards but it's not the reason for that is because card container here is not defined what we need to do is just create a query selector for that oops so we can just come in here and we can say card container is just going to be document.queryselector our card container just so we can add it to our container now if we save this though we just refresh our page and i scroll down you'll notice as soon as our last card is visible it's adding new cards at the bottom and if i get down to the bottom of our new set of last cards it's adding more as you can see our scroll bar just keeps getting smaller and smaller and we get new and new cards being added constantly to the page now one important thing that you're going to notice with intersection observer and when you're doing infinite scrolling is you probably want the thing to start loading before the last card is visible because usually you're doing like a network request which is going to take a bit of time so generally you're going to set your root margin here to like 100 pixels or something just so it starts the creation of those new cards before you actually get to the bottom of the list and depending on how slow your network request is you can make this bigger or smaller so now what happens is i start scrolling about 100 pixels before our card is visible on the screen it's going to add new cards as you can see our scroll bar just increased in size and now we have a bunch of new cards being added to the bottom and if i inspect our page just go over here to our elements tab look in our div you can see if we just scroll down as soon as i get to the bottom you can see a bunch of new cards are added and again once i get to the bottom we just added a bunch of new cards now if you enjoyed intersection observer you're going to love the resize observer and mutation observer i'm going to be creating videos on both of those and as soon as they're released they're going to be linked over here with that said thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 322,543
Rating: undefined out of 5
Keywords: webdevsimplified, intersection observer, intersectionobserver, intersection observer js, scroll animation js, scroll animation, lazy loading, infinite scrolling, lazy load images, lazy load images js, lazy load js, infinite scrolling js, javascript, js, intersection observer javascript, intersectionobserver js, intersectionobserver javascript
Id: 2IbRtjez6ag
Channel Id: undefined
Length: 15min 31sec (931 seconds)
Published: Tue Dec 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.