I'm displaying an element on scrolling down and hiding it when scrolling up again. Without using setTimeout, this works just as expected. However, using setTimeout causes the 'display' class to be added and removed in short intervals when scrolling down. How can I avoid this while keeping the delay?
onscroll = function() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 110) {
menuButton.classList.add('display');
} else {
setTimeout(function() {
menuButton.classList.remove('display');
}, 400);
}
}
I'm displaying an element on scrolling down and hiding it when scrolling up again. Without using setTimeout, this works just as expected. However, using setTimeout causes the 'display' class to be added and removed in short intervals when scrolling down. How can I avoid this while keeping the delay?
onscroll = function() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 110) {
menuButton.classList.add('display');
} else {
setTimeout(function() {
menuButton.classList.remove('display');
}, 400);
}
}
Share
Improve this question
asked Aug 8, 2014 at 18:35
GeorgGeorg
4981 gold badge6 silver badges15 bronze badges
3
- 1 Tried using clearTimeout to cancel the setTimeout? – j08691 Commented Aug 8, 2014 at 18:37
- Yep, but that doesn't fix it. – Georg Commented Aug 8, 2014 at 18:48
- Nervermind, setting that up correctly fixed it. Thanks! – Georg Commented Aug 8, 2014 at 18:57
2 Answers
Reset to default 2The timeout was still firing from earlier events. Here is my fix:
onscroll = function() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var timer;
if (scrollTop > 110) {
window.clearTimeout(timer);
menuButton.classList.add('display');
} else {
timer = window.setTimeout(function() {
menuButton.classList.remove('display');
}, 400);
}
}
You have to check the scroll position after the setTimeout
executes the function. It can be different after the timeout.
EDIT: If you don't want to the timeout to be triggered more than once you can clear it with clearTimeout
.
var timerId;
onscroll = function() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 110) {
menuButton.classList.add('display');
clearTimeout(timerId);
} else {
timerId = setTimeout(function() {
if (!(scrollTop > 110)) {
menuButton.classList.remove('display');
}
}, 400);
}
}