【问题标题】:if/else statement with setTimeout causes flicker带有 setTimeout 的 if/else 语句导致闪烁
【发布时间】:2014-10-02 07:45:38
【问题描述】:

我在向下滚动时显示一个元素并在再次向上滚动时隐藏它。如果不使用 setTimeout,这将按预期工作。但是,使用 setTimeout 会导致在向下滚动时在短时间内添加和删除“显示”类。如何在保持延迟的同时避免这种情况?

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);
  }
}

【问题讨论】:

  • 试过用clearTimeout取消setTimeout?
  • 是的,但这并不能解决问题。
  • Nervermind,正确设置它修复了它。谢谢!

标签: javascript


【解决方案1】:

超时仍在从早期的事件中触发。这是我的解决方法:

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);
  }
}

【讨论】:

    【解决方案2】:

    setTimeout 执行该函数后,您必须检查滚动位置。超时后可能会有所不同。

    编辑:如果您不想多次触发超时,您可以使用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);
      }
    }
    

    【讨论】:

    • 这并不能解决问题。即使 scrollTop 为 >110,else 语句似乎在滚动后执行了两次。
    • onscroll 事件可能会在触发setTimeout 之前多次触发。
    • 一定是这样。将间隔从 400 更改为 0 后,它工作得很好。那我该如何保持间隔呢?
    • 好的,我想通了。超时仍在从早期的滚动事件中触发(因为它被延迟了)。取消超时就成功了。
    猜你喜欢
    • 1970-01-01
    • 2021-09-21
    • 2019-07-29
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多