Problem
So I’ve made a button in the right-bottom corner of my HTML-page, but I was wondering since it’s the first time I’ve made this, if there is another better way to do this, or if you guys can see anything funky about the way I did this?
This post is mostly to learn how to do things the right way, since I’m a beginner at this.
Thanks for your help.
Here is my code –> if you want to GOTO: JSfiddle
var bottomPage = document.getElementById('bottomPage');
var topPage = document.getElementById('topPage');
var lastScrollTop = 0;
bottomPage.addEventListener('click', scrollBottom);
topPage.addEventListener('click', scrollTop);
// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
window.addEventListener('scroll', function(){ // or element.addEventListener('scroll'....
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st > lastScrollTop){
bottomPage.style.display = 'none';
topPage.style.display = '';
} else {
bottomPage.style.display = '';
topPage.style.display = 'none';
}
lastScrollTop = st <= 0 ? 0 : st;
}, false);
function scrollBottom() {
window.scrollTo(0,document.body.scrollHeight);
bottomPage.style.display = 'none';
topPage.style.display = '';
}
function scrollTop() {
window.scrollTo(0, 0);
topPage.style.display = 'none';
bottomPage.style.display = '';
}
body{
height: 3000px;
background: white;
background: linear-gradient(to bottom, #33ccff 0%, #ff99cc 100%);
}
.right-corder-container {
position: fixed;
right: 20px;
bottom: 20px;
vertical-align: middle;
background: #dddddd79;
text-align: center;
width: 40px;
height: 40px;
border-radius: 100%;
display: inline-flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 25px;
color: white;
font-weight: bold;
text-decoration: none
}
.right-corder-container img {
width: 40px;
height: 40px;
}
.right-corder-container:hover {
background: #85858579;
cursor: pointer;
}
<body>
<button class='right-corder-container' id='bottomPage' type='button'><img src='https://i.postimg.cc/87f0hmm2/scroll-down.png'></button>
<button class='right-corder-container' style='display: none;' id='topPage' type='button'><img src='https://i.postimg.cc/Tp4sL4gj/scroll-up.png'></button>
</body>
Solution
Some JS points
-
window is the default object. You seldom need to use it. eg
window.scrollTo
is the same asscrollTo
as iswindow.document
same asdocument
. -
You can use the element’s id as a JS variable name to reference an element.
-
For variables that do not change use constants const rather than var or let
-
Avoid setting style values directly to the elements style, rather use CSS rules and selectors to define the styles.
-
Keep your code out of the global scope by wrapping it in a IIFE (Immediately Invoked Function Expression)
HTML/CSS Design
-
There is no need to create two buttons. Use one button to simplify your JS.
Using CSS selectors to define rules for the buttons content lets you use one class name to switch between the up and down options. Add the class name for up, and remove for down.
-
There is no need for the
click
events to change the button state as thescroll
event will fire when you call Window.scrollTo and that function will change the button’s state/ -
You added a
type
attribute to button. This is not needed as the button is not part of a form. -
Why did you add the
document.documentElement.scrollTop
Element.scrollTop when Window.pageYOffset is zero?? The two values are the same! BTWpageYOffset
is an alias for Window.scrollY
Rewrite
The rewrite tries to keep the JS code a simple as possible.
I removed much of the custom styling (images, background) which can easily be added via HTML/CSS without needing to change the JavaScript
;(()=>{
var lastPos = 0, scrollToPos = document.body.scrollHeight;
scrollBtn.addEventListener("click", () => scrollTo(0, scrollToPos));
addEventListener("scroll", () => {
scrollToPos = scrollY > lastPos ? 0 : document.body.scrollHeight;
lastPos = Math.max(0, scrollY);
scrollBtn.classList.toggle("scrollUp", scrollToPos === 0);
}, false);
})();
body { height: 3000px }
#scrollBtn {
position: fixed;
right: 10px;
bottom: 10px;
cursor: pointer;
}
#scrollBtn > .top { display: none }
#scrollBtn.scrollUp > .top { display: initial }
#scrollBtn.scrollUp > .bottom { display: none }
<button id="scrollBtn">
<span class="top">Top</span>
<span class="bottom">Bottom</span>
</button>