Jonas: Let's now start working on the Bankist website,
and we're gonna start by implementing smooth scrolling
and the functionality that we're gonna implement now
is when we click on this button,
then it will smoothly scroll to this first section.
Okay, so that's it.
Simple fact all that happens is one click,
and the effect is that it smoothly scrolls
here to this first section.
So we're gonna see two ways of doing this.
First one a bit more old school,
which will allow me
to show you a couple of interesting stuff.
And then finally, I will show you the more modern way,
which only works in super modern browsers.
So let's start by selecting the button
and the section that we want to scroll to.
So that button is, it's this one,
btn--scroll-to, all right?
And then the section is this one, section--1.
So with this ID of section--1.
So const btnScrollTo
is document.querySelector.
All right, and now section1
is document.querySelector,
and now it's the ID.
So that's the hash
and then section dash dash one.
So that's the easy part.
And now as always, we need to start
by adding an event listener to the button.
.addEventListener on click.
And then our function, and let's actually give it the event.
So in the first way that we're gonna do, we need
to first get the coordinates of the element
that we want to scroll to.
So let me show you how.
So s1cords, and that's section1.getBoundingClientRect.
Alright, that sounds like a mouthful.
It's actually pretty straightforward.
Let me show it to you actually first.
So when I click this,
then we get this dome rectangle now, right?
And it has all of these properties.
So the exposition, which is measured from the left side,
the Y position, which is measured from the top,
and then the width of the element, the height,
and then a lot of other properties now, right?
And this element is probably not the best one
to understand this.
So let's get this rectangle for the button.
So that's the element we just clicked.
So e.target, remember?
So e.target is essentially this element here.
So the one that was clicked
and now getBoundingClientRect as well.
And so let's take a look at that second one.
So this 30 pixels here is the distance between the
border here of the browser, alright?
And then this Y is this distance from the top.
Then we also have the width, which is this 112, the height.
And yeah, here we also get the top,
which is in this case similar to Y, okay?
But it isn't always because when we scroll then X
and Y actually change.
So let me show that to you.
And if I click this again now,
then let's take a look here.
So you see that Y is now only 168 pixels.
And so that's the distance between this element
and the top of this viewport.
So this boundingClientRect is basically relative
to this visible viewport.
All right?
And in fact,
we can also get the current scroll position.
So since we're talking about scrolling, let me show
that to you as well.
So current scroll, so that's the X
and the Y positions, just so we see what we are looking at.
So these values are at window, pageXOffset,
and pageYOffset.
So let me just scroll somewhere here, click this.
And so we get that the current scroll is at zero from X,
so there's no horizontal scroll
and vertically, we already scrolled 290
pixels here at this point.
So when we're at the very top,
then these two values should both be zero.
And so yeah, now they are.
So basically this y coordinate here is the distance between
the current position here of the viewport
and the top of the page.
So here at this line, for example, when we're here,
if we get to scroll now, well now we can't
because we can click on the button.
But yeah, you get the point.
So the distance for example here is now 421.
So that means that from this very edge
of the browser right now all the way to the top of the page,
it is 421 pixels.
Okay, and sometimes that's very important
to know in certain applications.
And if you're even more curious than
since we're talking about coordinates
and stuff, we can also read the height
and the width of this view port.
So again, of this
rectangle in which we can see the current
portion of the page.
So height and width
of viewport, they are at document,
.documentElement.clientHeight,
and then the same with client width.
clientWidth.
Alright,
so you see that this high tier is 588,
and the width 10 67.
So if I change this here, so this is kind of half now,
so let's see what value we get now.
And so now it is 276. Okay?
And so that's because I decreased that visible box there.
And so the height of the viewport is of course different.
So let's reload here, click again.
And so yeah, here we get all kinds
of interesting information about coordinates, scrolling
and dimensions of the view port.
Alright?
But anyway, the goal of actually getting these coordinates
is because we need them to scroll
to this first section here.
Alright?
So basically we need these coordinates here
to tell JavaScript where it should scroll to.
So let's now do that actually.
So scrolling and we use window.scrollTo,
okay, so that's a global function
that's available on the window object.
And here the first argument is the left position.
And so that is at s1cords.
And let's take a look here.
So this is the one, now it's gone.
So we are interested here in this left value right now.
So it is zero and that's good
because we don't want any horizontal scroll.
Then for the second one,
we're gonna be interested in the top,
which is again the position from the top of the viewport.
So the section starts here.
So it's basically these 270 pixels right there.
Okay, so left
and s1cords.top.
So let's give it some more space and let's try it.
And indeed now it worked.
So we are now here at the top of section one. Okay?
And so that's because the top was at 730 pixels.
And so that's the distance that was scrolled.
However, watch what happens when I click again.
So now it doesn't really work, does it?
Well that's because this top here
that we specified is always relative to the view port,
but not to the document.
So not to the top
of the page basically, right?
So let me show it to you again so it works when we are here.
Alright?
And that's because this y position here, which is the same
as this top is 429,
which is basically the distance between this point
and this point, okay?
But if we're doing it here, then the distance
between the line and the top
of the viewport here is a lot less.
So it's only like 200 or something.
So let's see, it is only, actually it's only 112.
Well that doesn't make sense.
Well actually it's this one. So it's only 333.
Alright?
And so basically it only scrolls
to position 333 while in fact we wanted
to scroll all the way to here, which was at something like,
so it was at 492
or actually at 713.
Okay? So I know it's all a little bit confusing.
And in order to really understand all of these numbers,
you have to play around with this a lot by yourself.
Otherwise it's gonna be hard to make sense of this.
But the solution to this problem is
to simply add the current scroll position
to the top value here.
And with this we will then determine the position
of this section here, not relative to the viewport,
so to the top of this browser window here,
but instead to the top of the page.
Okay, so again, the position
of this section here is always this top, which is from here
to the viewport plus the current scroll position.
And so that's the distance from here all the way to the top.
Okay? So let's add that here.
And again to really make sense of all I'm saying here,
please play around with this a lot by yourself.
Okay, so pageYOffset.
And here it should actually also be window.
And then we also, just for the sake of completeness,
edit here as well.
So window.pageXOffset.
Okay? So let's see if it still works here and it does.
And now let's try it from somewhere else like here.
And now it works. Now it goes to the correct place.
And so by doing this here,
we basically determined the absolute position
of this element relative to the document,
so to the entire page.
And that's important to note.
So if you need that, then this is how you calculate it.
So again, the current position plus the current scroll.
Alright, now we can even make this better.
So .scrollTo again
because there is a way
of making this animation nice and smooth.
And this works by passing in an object now instead
of just one argument.
So let's get these two
and then let's comment all of this out.
And so the properties that we need to specify are the
left, so this is the left, this is the top.
And so this is actually called top.
And then we also have a property called behavior.
And so here we can now specify smooth.
Alright?
So to implement smooth scrolling like this, we need
to specify an object with the left top
and behavior properties.
So let's try it out and it works, great.
So that is a lot better, isn't it?
And again, it also is gonna work from this position
and the browser automatically figures out the speed it
should go to make this look really nice.
All right, so this is kind
of the old school way still of doing it.
So manually calculating all of these values here
and then saying that we want to scroll
to this position, all right?
But there is a more modern way, and it works like this.
We simply take the element that we want to scroll to
and that is section one.
And on that we call scrollIntoView,
and then we pass in an object and specify again behavior
and set it to smooth.
And that's actually it. Then we don't need any of this.
Okay, let me prove it to you. And it works just the same.
So without any of these weird calculations here,
with these weird positions
and all of that, it's all unnecessary if we are able
to use this function here.
And again, this only works in modern browsers,
but if you only need to support these,
then you are 100% fine using only this method.
But I think it was still a good idea to show you all
of these different numbers here.
So like calculating the current scroll positions
or the current window positions and sizes,
and also all the sizes of the elements
that we can get using this function.
And by the way, these client height
and width here are not counting with the scroll bars,
it's just the dimensions of the viewport
that are actually available for the content.
And of course that excludes any scroll bars.