最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ifelse statement with setTimeout causes flicker - Stack Overflow

programmeradmin1浏览0评论

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
Add a ment  | 

2 Answers 2

Reset to default 2

The 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);
  }
}
发布评论

评论列表(0)

  1. 暂无评论