Jonas: In this lecture, we're going to use JavaScript
to implement some nice animated scrolling.
Now, before we can actually animate some scrolling effects,
we first need to implement the scrolling
in the first place in HTML.
So right now, for example, if we click...
And let's turn this off.
So if we click, for example, here on one of these links,
then it will lead nowhere.
So it leads to this URL, which has this right here.
Right?
Because basically we just made it an empty link.
And so what we want, of course,
to happen is that when we click here,
it moves to the Meals section,
and here, it moves to the How It Works section,
and so on and so forth.
And we can actually do that just using HTML.
It will then not have the animated scroll,
but it will still work.
So let me show you how we can do that.
And I will first do it just with one of these buttons here.
So on this button here, when we click it,
we want it to move
to the call-to-action section, right?
Because that is where we can start eating well.
So let me show you how we can do that.
So let's go to that section here at the very end.
So this one here.
And now here we need to add an ID.
So we're back to using IDs,
but this time not to select the element in the CSS,
but really to give this element here a unique name.
So let's call this one cta. All right?
And then let's go back up to our link.
So that's this one here.
And so now here in the href,
we can write that here.
So #cta.
And what we just did here was to create a page anchor.
And so this here is what the anchor is.
So again, cta is the ID of the element.
And if we then use that as the href
of an anchor element together
with the hash symbol here,
then we will move to that place in the page.
So let me show that to you.
And when we hover over it,
you can already see that URL down there
in the bottom, right?
So now I'm gonna click. And there we go.
So we just moved automatically here to this section.
And you see that the URL indeed changed
to our regular URL first,
and then /#cta.
So if we remove this,
then we will go back up.
Right?
And so now we can do that basically on all our sections
and on all our links.
So this one here doesn't really need it
because it's just the first section in the page.
And we also don't want any link leading there.
And the same with the featured section.
So there's no link on the page
that should end up here in this section.
So no need for that.
And here, I'm simply calling them like a shorter name.
Not, again, section-how, but just how.
And of course any name would work here,
but I'm just doing it like this here.
So meals.
Then the next one is the testimonials,
which we also want.
So just copying that.
Then next we have pricing,
which I think is also one of the menu items.
And not class, but ID.
And the cta we already have.
So I think we're good here, right?
That was the last one.
And indeed it was. So let's go back up.
And now here in our menu,
let's create our correct anchors here.
So this one is called how.
So it will now lead to the element
with the ID of how.
And never forget this. So the hash.
Without this, it will not work at all.
Then, here, meals,
testimonials, pricing,
and finally, the try for free is cta.
Okay?
And so now maybe it makes sense why,
basically, an empty link is this one here.
It's basically also just an anchor
which will simply lead to the top of the page.
Right?
So it's not really in fact an empty link.
It's simply an anchor for the top of the page.
So down here we have that other button here.
So this link that is styled as a button
where we already set the cta anchor.
And now here for the learn more link,
let's simply make this one move to the first section.
So that's a very common practice.
All right. So I think we should be done.
So this one we already tested.
This one leads to the How It Works section,
This one here as well.
And let's really test all of them just to make sure.
So testimonials, nice.
Pricing. And finally, CTA.
Beautiful.
So we have everything now set up in the HTML.
And actually, if all you cared
about was the Google Chrome browser and also Firefox,
then you wouldn't need any JavaScript at all
to now animate these scrollings.
So let me show you
how we can actually animate scrolling behavior
just using CSS.
So for that,
I'm going to open up our general.
And then in body, so in the body selector,
we can set scroll-behavior to smooth.
All right?
So just to make sure,
let's remove all of this here.
And now when I click here,
let's see how it moves smoothly to the next section.
Well, that didn't really work,
so let's go back here.
And yeah, actually,
that scroll-behavior property should not be on the body,
but on the html.
All right. So that should fix it.
Let's delete this here.
And now let's see.
And indeed, that was a beautiful,
smooth scrolling animation.
All right? Here the same.
And it will, of course, work for all of them.
So that's really nice,
except for that it doesn't work
on the current version of Safari.
So if I copy this and open up Safari,
let's remove this part here,
then you see that as I click here,
we still have this kind of harsh jump
instead of a nice and smooth animation, right?
Now, the problem with this is that Safari is
in fact the only browser that is available
on the iPhone and iPad.
So even Google Chrome
on these devices actually uses Safari
as the rendering engine.
And so on all these devices,
so on all iPhones out there, it will not work.
So you will always then have simply this.
And this is really not good,
especially for a big page like this one
where if we click here,
and then it doesn't move there very smoothly,
it seems like this is an entirely new page, right?
So this harsh jump doesn't really show
that we are moving there.
While when we click here,
so if we click on Meals here,
then we can nicely see
that we're still on the same page
and that it simply moved there.
So the animation here is not really just
to make it beautiful,
but also to show the user what is going on.
Right?
And so we should fix this,
unless you are like watching this maybe
in like 2024 or '25.
Then you might be okay,
and all the latest versions
of Safari might already have this.
But at this point,
we should now write some JavaScript
to implement this functionality for all browsers.
Okay?
So let's move back here and turn this off.
Does not work on Safari
and also not on Microsoft Edge.
So maybe right now it does.
I'm not sure because they're using the same engine
as Google Chrome.
But some time ago, it also didn't work there.
And yeah.
Again, the best thing to do is
to just write some JavaScript here to fix that.
And that will not be the only problem we have with Safari.
So the next lecture, or the one after that,
here, you see that all this code
is also for fixing something in Safari.
But let's not get ahead of ourselves
and just work here
on the smooth scrolling animation.
Okay.
Now, this one will be a little bit more complex
than the one that we did before,
but I will just explain everything step by step,
and then the code at least should make sense,
even though, as I said before,
I will, of course, not expect you to be able
to write this sort of code
after just watching these few lectures here.
For that, you would have
to take probably an entire JavaScript course.
But anyway, let's now select all the links
on the page, basically.
So let's say allLinks.
So document querySelector.
And now it is actually querySelectorAll.
So when we want more than just element,
we need to do this.
And now we can simply use the a selector, right?
And so that will then select only the links.
And to make it even better,
we can also use the link pseudo class here.
So just like this.
And so then just like in CSS,
this will only select anchor elements
which actually have the href property.
So again, just like in CSS.
Right?
Now, just to see,
let's take a look at this in the console.
All right. So let's inspect this back here.
And so you see now we get this thing here
which is called a NodeList.
And then you see
that here we have all
of these anchor elements, right?
Now, next we need to add an event listener
to each of these links, just like we did here before.
So in the exact same way
because now, again, we want to listen for a click event.
So we want something to happen
whenever the user clicks on one of these anchors.
All right?
So allLinks,
but now we cannot just write addEventListener like this.
Because as we just saw,
the allLinks are multiple elements.
And so we need to add the addEventListener
to each of them individually.
So we can write forEach.
Then, here, we need to,
just like before, write a function.
And then here we need to specify basically
that each of these elements in the allLinks is a link.
And this name here could, of course,
be anything they wanted.
Could be just l,
but I like to call it here link, in this case.
And so now here is
where we have basically the individual link.
And then we can addEventListener here like before.
There would actually be a cleaner way
of doing this called event delegation,
but let's not go into that right here.
So just like before,
here, we specify a function.
And here, we did actually give this a name.
Again, so this so-called parameter in this function.
And this e here stands for event
because we actually do have access
to the event that happens.
So let me show that to you also in the console.
Okay?
And so now the only thing that will happen
is that whenever we click on one of the links,
we will get the event object logged to the console.
So let's try this one here.
And indeed, we get a mouse event.
So here we have, then,
all this kind of data here, which we don't really need.
I just wanted to show you
that we do get access to that event,
and it has a bunch of data on it.
Now, this is important here
because as you see
that the page actually moved here, right?
Because, of course, that is the default behavior
of the anchor.
Okay?
But now we actually need to turn that default behavior off
so that we can implement our own.
So preventDefault.
And so now if we try that again,
so coming up here,
so if I now click, then nothing should happen.
And indeed, it did not.
All right?
And by the way,
if you're not really interested
in the code that I'm writing here,
you can just skip this video
and simply take the code here
from the final file of this section.
All right?
You don't have to go through this
if you're not interested in JavaScript.
Okay?
But if you are interested, then let's keep going here.
And the first thing I'm going to do is
to now read basically the href attribute
out of the link that was clicked.
Because we will then use that href
to actually scroll to the corresponding section.
So that is link.getAttribute
with the name of href.
And again, let's log that to the console.
So href, all right?
And here, again, I could have given it any name,
but here not.
So here, the name of the attribute
that we want to get from each link is really called href.
So really this here, for example, right?
So the name is href.
And so here we are reading that attribute.
So let's see.
When I click here, then we get cta.
And here, we should get how, right?
Because, well, that's where we set the anchor to.
So we can see that down there also.
Okay.
And now we actually have everything
to implement our scrolling functionality.
And let's start with the one
that scrolls back to the top.
So scroll back to top.
And so those are these ones here.
So this link for example,
which has just the hash,
and also like, the one here in the footer.
So this one is also just hash, right?
And so this one
and the one at the top,
we want them to scroll back to the top.
So we can say
if the href is equal to just this,
so what we just saw in the browser,
then the window should scroll to...
So you see that all of this reads kind of like English.
Now, here we specify this object of options,
and we say the top should be zero pixels,
and the behavior should be smooth.
All right. And that's it, actually.
So at least for this type of link.
So if I click this now,
then it moves back smoothly to the top.
And the same here.
And it is the top because we set it here to zero.
So we could have set it like to 20,
and then it would move like to 20 pixels off the page.
We saw that.
So not really to the top,
but of course we want it to be zero here.
Now, the thing is that not even this here does work
by default in Safari,
but there is a fix for that.
So we can just include this line of code here in our HTML.
So this is what we call a polyfill,
which is basically a JavaScript library
which implements this functionality for Safari.
So let's copy this.
So go ahead and select this text here,
and then copy it.
And then we need to also edit here
as a script just like we did here with these ionicons.
So this was an external script
that was loaded from somewhere else,
and this was basically an internal script
that is loaded from our own page.
And now we will add this other script
that I just mentioned.
So also defer, then source,
and then what we copied before.
All right? Give it a save.
And so, yeah,
let's copy this here now and try it out in Safari.
Well, we can just come here back to the top,
and then let's move down and click on this one.
And whoa, what's happening there?
Well, that was just something strange from before,
but what matters here is that now it did scroll smoothly
to the top.
All right?
Now, of course, these others do not work yet
because, well, we didn't implement them yet.
Yeah, right here, actually.
So we only implemented here the smoothing scrolling
for when the href is exactly this one here.
Right?
But then we also have some other situations.
So basically, where the href is not just that.
So href is different than just this.
And at the same time,
href starts with that.
Okay?
Now, here we could also have said
or tested for this situation
in which href starts with this one
and is longer than just one character,
but that's really the same here.
Okay?
And now this here works a little bit different.
So for now, let's again just log it
to the console so I can then show you the technique
that we're going to use here.
So in this case,
log href to the console.
Okay? Let's test that here.
And so when we click here,
it now should log that to the console.
And actually, that happened twice
because we still have this part from before.
But let's go back.
So if we click here, it appears once.
And so that is because it starts with the hash,
but it is not just that.
And so if we click here,
then nothing appears in the console.
All right?
So basically because it does not pass
this testing condition here.
All right?
But anyway, what matters is that this string here,
so this text,
looks somehow like a selector
for an ID, right?
So remember how the hash is the ID selector in CSS.
Right?
And we can very easily check that by copying this.
And then let's say just here,
this is just for testing,
let's say background: blue.
Right?
And let's see.
And indeed, there it is.
So this is basically an ID selector because,
yeah, the hash here selects for elements
which have the ID of this here.
So of cta, in this case.
And so we can use that also
to our advantage in the JavaScript.
So we can now select the element basically based on that.
So we can say document.querySelectorAll.
And then here, remember that we have to write the selector.
And so the selector can simply be the href.
Right?
For example, just like #cta.
So let's actually again log that to the console.
And here, if we have more than one line of code,
we need to start a new block with these curly braces.
So let's call this the section element
that we want to scroll to.
And then let's log that to the console.
All right, so let's move back up here.
So you see that now we got the element here
that we want to scroll to.
So basically, the element that has the ID
that is equal to the href of this element right here.
So you see it is exactly this element here.
And here, if we click on the Meals,
we, of course, get this other one.
So this one, right?
And so now we just need one final piece
of the puzzle here,
which is to say
sectionElement.scrollIntoView
with the behavior,
and you can guess it, of smooth.
And that's actually it.
So here, we could not use the scrollTo
because we wouldn't know which pixel value
from the top we would want to scroll to.
Right?
And so instead, we can use this scrollIntoView function.
So let's test that.
And yeah, that works beautifully.
And on all of them, of course, it should work.
And now the final test on Safari.
And yes, beautiful.
That is really nice, really amazing.
So we just implemented smooth scrolling on all browsers.
Now, just one final thing.
So let me switch back here
to the mobile view, which is...
Let's make this a bit bigger actually.
So when we switch,
so when we turn on our navigation,
then let's say we click here.
So we smoothly moved here.
And so that's exactly as expected.
However, if we move back up,
then our navigation is still here, of course.
And that makes sense, right?
I mean, why wouldn't it?
There is nothing telling it that it should disappear.
However, this is not really practical, right?
So whenever we click on one of these links here,
basically, we will want the navigation to close.
Right? So we want this year to disappear.
Well, that is not all too hard to do.
So what we're gonna do is this.
So moving back here to our HTML,
these links that are in the navigation,
they all have this class name here, right?
And so what we can do is
to check if the current link has this class name.
And if it does, then we just do this here.
So we then just remove the nav-open class.
Okay?
So let's keep adding some comments here
to structure our code.
So scroll to other links.
And finally, close mobile navigation.
So first off, we need to check
if the link has that class of main nav-link.
And the way we do that is a little bit similar
to what we did here.
So with this classList.
So we can say link.classList,
but now instead of toggle,
we can say contains.
So classList.contains.
And so this basically asks the question,
is this class,
so is main-nav-link
inside of the class list of the link that we just clicked?
Okay?
And so if it is,
then we say basically what we have here.
So let's just grab that.
And that's it.
So again, we basically reach into the list
of classes of the link.
And so if it contains the main-nav-link,
and so that's how we identify the five links
that are here in the main-nav,
then we want to toggle the nav-open.
So basically removing that nav-open if it is on the header.
So let's test that again.
And we could already see
that it was fading out, right?
And so it's gone.
And so with this,
we actually have everything working now beautifully.
And just to make sure,
let's also test it here,
just making it smaller.
All right, pricing.
And it's gone now here as well.
All right. Beautiful.
So yet another small effect here completed.
So great job.
And so let's move on to the next one
where we will create a so-called "sticky navigation."
So in other words,
where we will make this navigation bar here stick on the top
throughout the entire page.
So making it appear up here.
So that's going to be really exciting as well.
So hopefully I see you there soon.