I wanted to implement a simple top and bottom scroll on button click. the scroll should be smooth in all browsers.
Requirements -
I have two buttons on the page, on top of the page there is a button called Down on clicking on that It should go down to the footer div.
There is one more button on the bottom of the page called UP on clicking on that It should go up of the screen.
I have tried one solution but in IE, the scroll is not smooth. How can we make the scroll behavior smooth in all browsers.
Currently I have used the scroll-behavior property in CSS but is it a good practice? Is there any way to do it in JavaScript instead of CSS?
html{
scroll-behavior: smooth;
}
NOTE: It should also work in IE.
I would really appreciate your help.
Link of codepen for code-
I wanted to implement a simple top and bottom scroll on button click. the scroll should be smooth in all browsers.
Requirements -
I have two buttons on the page, on top of the page there is a button called Down on clicking on that It should go down to the footer div.
There is one more button on the bottom of the page called UP on clicking on that It should go up of the screen.
I have tried one solution but in IE, the scroll is not smooth. How can we make the scroll behavior smooth in all browsers.
Currently I have used the scroll-behavior property in CSS but is it a good practice? Is there any way to do it in JavaScript instead of CSS?
html{
scroll-behavior: smooth;
}
NOTE: It should also work in IE.
I would really appreciate your help.
Link of codepen for code- https://codepen.io/Akkanksha1/full/KKgWmgL
Share Improve this question edited Dec 20, 2020 at 18:59 Or Assayag 6,35613 gold badges72 silver badges108 bronze badges asked Dec 15, 2020 at 10:54 Akanksha MohantyAkanksha Mohanty 7011 gold badge8 silver badges19 bronze badges 12-
scroll-behavior
does not work in IE. – Not A Robot Commented Dec 15, 2020 at 10:58 - Is there any way to make it scroll smooth in IE @NotABot – Akanksha Mohanty Commented Dec 15, 2020 at 11:02
-
You can try the
scrollTo
method in JavaScript to achieve somewhatscroll-behavior
is doing. You need to know the dimensions(height and width) in px of the page then accordingly you can achieve. @Akansha Mohanty – Not A Robot Commented Dec 15, 2020 at 11:05 - @AkankshaMohanty, Does IE mean the discontinued IE or Edge? Cause you won't find a easy way to do it in IE. You will need a library. – Nikhil Patil Commented Dec 15, 2020 at 11:22
- Yes I searched a lot for a solution that works on IE as well but I didn't find any proper solution. If you will check the codepen link then It is working in IE but not smooth. so is there any way that we can use javascript to add the scroll behavior property as I have used css for that.@NikhilPatil – Akanksha Mohanty Commented Dec 15, 2020 at 11:36
5 Answers
Reset to default 4 +25This solution is written in ECMAScript 5 and makes use of requestAnimationFrame()
in order to synchronize the step calculations with the screen framerate. It works in IE and in modern browsers as well.
It implements the easeInOutCubic
function, and could be extended to support other easing functions.
function getProgress(_ref) {
var duration = _ref.duration,
runTime = _ref.runTime;
var percentTimeElapsed = runTime / duration;
function easeOutCubic(x) {
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2 ;
}
return easeOutCubic(percentTimeElapsed);
};
function getTotalScroll(_ref) {
var scrollableDomEle = _ref.scrollableDomEle,
elementLengthProp = _ref.elementLengthProp,
initialScrollPosition = _ref.initialScrollPosition,
scrollLengthProp = _ref.scrollLengthProp,
direction = _ref.direction;
var totalScroll;
var documentElement = document.documentElement;
totalScroll = documentElement.offsetHeight;
return !!~['left', 'top'].indexOf(direction) ? initialScrollPosition : totalScroll - initialScrollPosition;
};
function smoothScroll(_ref2) {
var scrollableDomEle = window,
direction = _ref2.direction,
duration = _ref2.duration,
scrollAmount = window.outerHeight - window.innerHeight;
var startTime = null,
scrollDirectionProp = null,
scrollLengthProp = null,
elementLengthProp = null,
scrollDirectionProp = 'pageYOffset';
elementLengthProp = 'innerHeight';
scrollLengthProp = 'scrollHeight';
var initialScrollPosition = scrollableDomEle[scrollDirectionProp];
var totalScroll = getTotalScroll({
scrollableDomEle: scrollableDomEle,
elementLengthProp: elementLengthProp,
initialScrollPosition: initialScrollPosition,
scrollLengthProp: scrollLengthProp,
direction: direction
});
if (!isNaN(scrollAmount) && scrollAmount < totalScroll) {
totalScroll = scrollAmount;
}
var scrollOnNextTick = function scrollOnNextTick(timestamp) {
var runTime = timestamp - startTime;
var progress = getProgress({
runTime: runTime,
duration: duration
});
if (!isNaN(progress)) {
var scrollAmt = progress * totalScroll;
var scrollToForThisTick = direction === 'bottom' ? scrollAmt + initialScrollPosition : initialScrollPosition - scrollAmt;
if (runTime < duration) {
var xScrollTo = 0;
var yScrollTo = scrollToForThisTick;
window.scrollTo(xScrollTo, yScrollTo);
requestAnimationFrame(scrollOnNextTick);
} else {
var _scrollAmt = totalScroll;
var scrollToForFinalTick = direction === 'bottom' ? _scrollAmt + initialScrollPosition : initialScrollPosition - _scrollAmt;
var _xScrollTo = 0;
var _yScrollTo = scrollToForFinalTick;
window.scrollTo(_xScrollTo, _yScrollTo);
}
}
};
requestAnimationFrame(function (timestamp) {
startTime = timestamp;
scrollOnNextTick(timestamp);
});
};
function scrollToTop() {
smoothScroll({ duration: 2000, direction: 'top' });
}
function scrollToBottom() {
smoothScroll({ duration: 2000, direction: 'bottom' });
}
document.getElementById('scroll-to-bottom').addEventListener('click', scrollToBottom);
document.getElementById('scroll-to-top').addEventListener('click', scrollToTop);
.container {
position: relative;
height: 1000px;
background-color: red
}
#scroll-to-bottom {
position: absolute;
top: 0px;
}
#scroll-to-top {
position: absolute;
bottom: 0px;
}
<div class="container">
<button id="scroll-to-bottom">Scroll to bottom</button>
<button id="scroll-to-top">Scroll to top</button>
</div>
I have found a solution that works in Chrome and also in other web browsers like IE and Mozilla. My goal was to have a up & down scroll on the page and the below code works like a magic for me.
JS Code -
//Get the button
const scrollToTopBtn = document.getElementById("scrollToTopBtn");
const scrollToBottomBtn = document.getElementById("scrollToBottomBtn");
// When the user scrolls down 1000px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 1000 || document.documentElement.scrollTop > 1000) {
scrollToTopBtn.style.display = "block";
} else {
scrollToTopBtn.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
window.scrollTo({ top: 0, behavior: 'smooth' })
};
function bottomFunction(){
document.getElementById('site-footer').scrollIntoView({behavior: "smooth"});
}
scrollToTopBtn.addEventListener("click", function(e){
e.preventDefault();
topFunction();
});
scrollToBottomBtn.addEventListener('click', function(e){
e.preventDefault();
bottomFunction();
});
Working demo - https://codepen.io/Akkanksha1/full/KKgWmgL
@AkankshaMohanty this all depends on how far you would like to go back, as in IE 11? Or further back? Are polyfills ok?
Well anyway, without further ado, the most primitive way can be the best.
Classic jQuery approach, this should work with older jQuery versions(the new version do not support IE anymore)
$('html, body').animate({
scrollTop: $("#myElem").offset().top
}, 1000);
The scroll up or down you may implement yourself, but the main cross browser issue is a non issue with the above code, something like jQuery 1. or 2. should work.
here is a plugin to make it work http://erraticdev.blogspot./2011/02/jquery-scroll-into-view-plugin-with.html, there are some other polyfills which I am not going to link to. With requirements like "work in IE without a fallback option" , elegance is the first victim.
You dont need any large code. Just you need scrollTop
property. It indicates the distance scrolled from top. To go to top you just have to set it to 0 and to go to bottom you have to scroll to maximum height.
To make it smooth it is better to go to custom approach to provide cross platform support. For example you can see the code which is self explanatory and ready to use
function scrollToTop(){
var interval=setInterval(()=>{
var i=document.body.scrollTop;
document.body.scrollTop=i-1;
if((i-1)===0){
clearInterval(this);
}
},30)
}
function scrollToBottom(){
var maxHeight=document.body.offsetHeight-window.clientHeight;
var interval=setInterval(()=>{
var i=document.body.scrollTop;
document.body.scrollTop=i+1;
if((i+1)===maxHeight){
clearInterval(this);
}
},30)
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("a").on('click', function(event) {
if (this.hash !== "") {
event.preventDefault();
var hash = this.hash;
$('html, body').animate({scrollTop: $(hash).offset().top}, 800, function(){
window.location.hash = hash;
});
}
});
});
</script>
<style>
#section1 {
height: 600px;
background-color: pink;
}
#section2 {
height: 600px;
background-color: purple;
}
a {
color: yellow;
font-size: 20px;
}
</style>
</head>
<body>
<h1>Click on the link to see the "smooth" scrolling effect.</h1>
<div class="main" id="section1">
<h2>Section 1</h2>
<a href="#section2">Click Me to Smooth Scroll to Section 2 Below</a>
</div>
<div class="main" id="section2">
<h2>Section 2</h2>
<a href="#section1">Click Me to Smooth Scroll to Section 1 Above</a>
</div>
</body>
</html>