-1

I need to show/hide two floating buttons on page scrolling for back to top and back to bottom. Here is my code.

It should shows, back to top button while scrolling page to bottom (it works) and shows back to bottom button while scrolling page to top.(not working properly)

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {
  scrollFunction()
};

function scrollFunction() {
  if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 300) {
    document.getElementById("toTop").style.display = "inline";
    document.getElementById("toBottom").style.display = "none";
  } else {
    document.getElementById("toTop").style.display = "none";
    document.getElementById("toBottom").style.display = "inline";
  }
}

// When the user clicks on the button, scroll to the top of the document
function topFunction() {
  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;
}

// When the user clicks on the button, scroll to the bottom of the document    
function botFunction() {
  let height = document.body.clientHeight;
  document.body.scrollTop = height;
  document.documentElement.scrollTop = height;

}
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 20px;
  }
#toTop {
  display          : none;
  position         : fixed;
  bottom           : 20px;
  right            : 30px;
  z-index          : 99;
  font-size        : 18px;
  border           : none;
  outline          : none;
  background-color : red;
  color            : white;
  cursor           : pointer;
  padding          : 15px;
  border-radius    : 4px;
  }
#toTop:hover {
  background-color : #555;
  }
#toBottom {
  display          : none;
  position         : fixed;
  top              : 20px;
  right            : 30px;
  z-index          : 99;
  font-size        : 18px;
  border           : none;
  outline          : none;
  background-color : red;
  color            : white;
  cursor           : pointer;
  padding          : 15px;
  border-radius    : 4px;
  }
#toBottom:hover {
  background-color : #555;
  }
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>


<button onclick="topFunction()" id="toTop" title="Go to top">↑</button>
<button onclick="botFunction()" id="toBottom" title="Go to top">↓</button>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
Amir
  • 4,089
  • 4
  • 16
  • 28
  • I don't understand what you are asking. you want that only one button to be visible at time? yet logically if the scroll is in the middle, the 2 buttons should appear, right? – Mister Jojo Nov 16 '22 at 23:21
  • @MisterJojo ، definitely yes – Amir Nov 17 '22 at 05:36

2 Answers2

1

For that purpose, I would include detection of the scroll direction.

By using it, your code could look like this:

let previousScrollY = 0; //Store previous scroll to detect if the next one is going up or down

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {
  if (previousScrollY > this.scrollY) {
    return scrollFunction('up'); // Or just scrollFunction() as we are not using "up"
  }
  previousScrollY = this.scrollY
  return scrollFunction('down');
};

function scrollFunction(direction) {
  if ( 
    (document.body.scrollTop > 300 || document.documentElement.scrollTop > 300) &&
    direction === 'down'  
  ) {
    document.getElementById("toTop").style.display = "inline";
    document.getElementById("toBottom").style.display = "none";
  } else {
    document.getElementById("toTop").style.display = "none";
    document.getElementById("toBottom").style.display = "inline";
  }
}

// When the user clicks on the button, scroll to the top of the document
function topFunction() {
  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;
}

// When the user clicks on the button, scroll to the bottom of the document    
function botFunction() {
  let height = document.body.clientHeight;
  document.body.scrollTop = height;
  document.documentElement.scrollTop = height;

}
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 20px;
  }
#toTop {
  display          : none;
  position         : fixed;
  bottom           : 20px;
  right            : 30px;
  z-index          : 99;
  font-size        : 18px;
  border           : none;
  outline          : none;
  background-color : red;
  color            : white;
  cursor           : pointer;
  padding          : 15px;
  border-radius    : 4px;
  }
#toTop:hover {
  background-color : #555;
  }
#toBottom {
  display          : none;
  position         : fixed;
  top              : 20px;
  right            : 30px;
  z-index          : 99;
  font-size        : 18px;
  border           : none;
  outline          : none;
  background-color : red;
  color            : white;
  cursor           : pointer;
  padding          : 15px;
  border-radius    : 4px;
  }
#toBottom:hover {
  background-color : #555;
  }
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>


<button onclick="topFunction()" id="toTop" title="Go to top">↑</button>
<button onclick="botFunction()" id="toBottom" title="Go to top">↓</button>
Alvin
  • 762
  • 4
  • 14
  • I like this design, but the implementation is quirky. I think it's caused by the 300px and direction conditions. Perhaps remove the 300px and only use direction? Still, worth +1 – Yogi Nov 17 '22 at 00:15
  • Your idea is good, but not working as expected – Amir Nov 17 '22 at 05:47
0

I will do that this way...

const
  scope       = document.documentElement
, btGoBot     = document.querySelector('#toBottom')
, btGoTop     = document.querySelector('#toTop')
, borderDelta = 300
  ;
window.onscroll = btTopBotShow;
window.onresize = btTopBotShow;

btTopBotShow(); // on page load...

btGoBot.onclick = () =>
  {
  scope.scrollTop = scope.scrollHeight - window.innerHeight;
  }
btGoTop.onclick = () =>
  {
  scope.scrollTop = 0;
  }

function btTopBotShow()
  {
  let bottomDelta = scope.scrollHeight - window.innerHeight - scope.scrollTop;

  btGoBot.classList.toggle('noDisplay', bottomDelta     < borderDelta )
  btGoTop.classList.toggle('noDisplay', scope.scrollTop < borderDelta )
  }
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 20px;
  }
#toTop,
#toBottom {
  position         : fixed;
  right            : 30px;
  z-index          : 99;
  font-size        : 18px;
  border           : none;
  outline          : none;
  background-color : red;
  color            : white;
  cursor           : pointer;
  padding          : 15px;
  border-radius    : 4px;
  }
/*
#toBottom { top    : 20px; }
#toTop    { bottom : 20px; }
*/
#toBottom { top : calc( 50vh - 60px ); }
#toTop    { top : calc( 50vh +  4px ); }

#toTop:hover,
#toBottom:hover {
  background-color : #555;
  }
.noDisplay {
  display : none;
  }
0 top <br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br>
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9<br><br> 
  0<br><br> 1<br><br> 2<br><br> 3<br><br> 4<br><br> 5<br><br> 6<br><br> 7<br><br> 8<br><br> 9 bottom
  
<button id="toBottom" title="Go to botton" >↓</button>
<button id="toTop"    title="Go to top"    >↑</button>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
  • Nearly good. But better if buttons appear at the middle of the screen near each other and just one of them at each time . – Amir Nov 17 '22 at 05:54
  • @Amir This positioning of the buttons is yours. why ask here to have only one button visible at a time, when you answered positively to my question on the fact that the 2 buttons can be visible at the same time when the scroll is in the middle? there is also a rule here, if you have the right to change your ideas, but not the question... – Mister Jojo Nov 17 '22 at 15:34
  • Yes, at the middle, show both of them. It's just a moment. Not important so much. Maybe at a moment switch showing them is better – Amir Nov 17 '22 at 16:17
  • @Amir `at a moment`, it's a bit of a vague definition; there is no command like 'if (at_a_moment) showButton('toBottom')` and 'if (at_another_moment) showButton('toTop')` in javascript. – Mister Jojo Nov 17 '22 at 16:29
  • No, I think it should appear based on direction. I mean if scrolling down, it should shows back to top and if scrolling up, it should shows back to bottom. If no scrolling, none of buttons appear. Your code is good but I like a brilliant minimal code. A WOW code! – Amir Nov 20 '22 at 04:27