Join Ray Villalobos for an in-depth discussion in this video Tracking our navigation with ScrollSpy and jQuery, part of Bootstrap Layouts: Responsive Single-Page Design.
So let's go ahead and click back up here to ScrollSpy, and show you how it works. You can do it without any scripting by adding the data-spy="scroll" to the element that you want to spy on, which is almost all the time the body tag. Then you add the data-target attribute to that same element with the ID of what you want to track. So on our case we would put all this in the body tag. Notice that it does ask you to use a position: relative in the body selector.
We've already done that. When we were doing the styles for our page, we automatically added this position: relative. I told you we were going to need that later, and this is when we need. So if you haven't done this, make sure you add position: relative into your page. Then we can just go to the index.html document and add data-spy as an attribute here, and we'll make that "scroll". Then we can do a data-target.
Here we want to put a class or ID of an element on our page. We want to target the navigation and so we can use any of these classes. So, for example, I could use something like navbar-fixed-top, and I'm gonna save this. Now notice that as I scroll down on the page, as soon as I get to a different section, it's gonna highlight that section, and that's pretty cool. Let's go into the Services and there it is. That's awesome. That's what we need.
So what we want to pass along here is the target just like we were doing with HTML. Here I'm gonna type in header.navbar. We could've typed in the other navbar-fixed-top if we wanted to, but you can also just target with any sort of selector that you want. So I'm just trying a different one. This should work just fine. Let's go ahead and save that, and see if it's working. When we go to a new section, it should highlight it.
The other thing that I want to do is make sure that when my navigation sort of scrolls past this top part ... What I'm gonna do is I'm gonna change this style of this nav to be a little smaller. I also need to pass along an offset, which is gonna fix the problem of the item activating too soon when we have a smaller nav bar at the top. So I'm gonna say offset and I'll do topoffset. That's a variable that I'm gonna create.
So let's do that, var topoffset, and I'm gonna set it to 50 for right now. All right, let's go ahead and save that. Although it's working, what we want to do now is make sure that we change our menu whenever somebody has scrolled down the top part of the browser. So one of the other options that you have with the ScrollSpy plugin is that a bunch of methods become active for you.
So, for example, let's go ahead and go down here. There's a few methods that sort of fire whenever something happens with ScrollSpy. One of them is called activate.bs.scrollspy, so bootstrap scrollspy. That event fires whenever a new item becomes activated by the ScrollSpy. So that's what we want to target right now. Whenever a new item becomes activated, we're gonna look for a certain item. That event fires so we can trap it and then do something with it. That's what we're interested on right now.
So right here I'm gonna create a variable called hash and I'm gonna set it to ... Actually let's go ahead and ... Actually, no that's find editor, I'm sorry. So I'll create a variable. I'm gonna called it hash. I'm going to ask it to look for the current pages. We're executing a find function. We're gonna look for a list item that has a class of active, right? We're gonna look for that link. Then do something with that link.
We're gonna look for the attribute called href. So what is that doing. So if we look at the code for these elements. Let's go inspect element. You'll see that what's happening is as I scroll down these list items are getting a class of active. So let's scroll down to another section. Notice that now this one is the active one. If I scroll up you'll see that this one is now active. You can tell that the one I'm currently on is the Services one.
Let me open this little triangle up. If I scroll down, now I'm in Staff. So what I'm doing here is saying, hey, on the document find a list item that has an active class and look for the a tag or the anchor tag. Then find the href attribute, so that would be the attribute right here, href. Right now it's #services. Then put that information in this hash variable. That's gonna store the location of the current page.
Now what we can do here is if that hash variable is not our featured item, so I'll do #featured item, because that's the very top one, and it's the one that's gonna be highlighted at the beginning. So this active one right now, notice that the home page has this #featured. That is gonna be what is active at the very top of the page. I'm really interested in what happens once it goes past this home section or the featured ID, right? Once it gets to here, then I want to know and so that's what I'm doing.
I'm saying, hey, if the hash is not the first one or the one with the ID of featured, then I want to do something. What I want to do here is say I'm going to header nav. So I'm gonna target the header navigation, and I'm gonna add a class to it, and call it inbody. So that is going to allow me to see when the user has scrolled past a certain section, and then it's gonna add a class to this navigation tag.
So the nav tag would be right here. Once I have that class, I can target that with CSS. So what I also need to do is make sure that otherwise it's going to ... Instead of adding a class ... So if we scroll back up to the top, right? Then what I want to do is remove a class and body just in case one exists. So all this needs to be placed inside the event.
Boostrap scrollspy, so when one of those events fires, then I want to execute a function. This is a callback, right? So when that happens I want you to do the following, and I want you, essentially, to do all this. So let's go ahead and indent this in. We'll make sure we add a comment.
Okay? Let's go ahead and save. Come back over here and take a look at ... Let's go ahead and just load the page from scratch. We'll scroll down and whenever we get to a different section, notice that the navigation has activated here. But in addition to that, it's adding this class inbody in our navigation, which means that we can now target that with CSS. Notice that when I scroll up when it goes back into the home page, it means that that class needs to go away.
So notice that it's no longer here. So let's just highlight that again. If I scroll down the inbody class shows up in the nav. If I scroll up, it's gone. So that's exactly what we need. Now there's a little bit of a problem. If I click on Services, it goes to the Services section. Now if I reload the browser, notice that my inbody nav is not there. That's because somebody has linked directly to this page, and therefore, the scrollspy event hasn't been fired.
That one only fires whenever a change happens. So whenever I scroll, you'll see that the inbody event or the inbody class gets added. But if somebody reloads, it's not gonna add that necessarily to our page. So we need to go ahead since it fired already, it's already there. But if somebody were to link to one of our other pages, that class would not be in the right place. So we're just gonna grab all this stuff right here and make sure that we do exactly the same thing.
But not just when this event happens, just do it kind of at the beginning whenever our page loads. Now when we refresh, let's go ahead and go to Services and refresh the browser. Now it's always gonna happen because as soon as we go to anywhere in our page, even if we're linking directly, it's gonna do that test, and notice whether or not we are at the very top of the page. Or so when I go to the top, that class disappears. When I go anywhere on the page, it's also gonna fire the proper event that's gonna target this.
- Analyzing your markup
- Creating simple column layouts
- Creating basic navigation and a simple carousel
- Modifying Bootstrap styles
- Working with branding and toggle styles
- Adding interactivity