Twitter上的setTimeOut()解决方案

时间:2011-04-12 08:27:43

标签: jquery twitter

我正在阅读John resig的博文:http://ejohn.org/blog/learning-from-twitter/,我不明白setTimeOut()的问题。

问题1:

Johh分享了这段代码:

var outerPane = $details.find(".details-pane-outer"),
    didScroll = false;

$(window).scroll(function() {
    didScroll = true;
});

setInterval(function() {
    if ( didScroll ) {
        didScroll = false;
        // Check your page position and then
        // Load in more results
    }
}, 250);

这里使用的缓存在哪里?我假设当didScroll为true时,将使用outerPane变量而不是重新搜索DOM,我是对的吗?


问题2:

在评论部分,迈克尔共享了一段代码:

var timer = 0;

$(window).scroll(function () {
if (timer) {
clearTimeout(timer);
}

// Use a buffer so we don't call myCallback too often.
timer = setTimeout(myCallback, 100);
});

并说:“而不是设置一个间隔,回调只是在它需要时被触发。保存一些额外的回调调用,并且滚动处理程序内的额外逻辑的任何开销应该相当小。

我的问题是:setTimeOut()将返回一个timerID,clearTimeOut将使用它来清除。现在有了这个setTimeout(myCallback,100)函数,每隔100毫秒后就会使用myCallBack函数,不是吗?此外,当滚动事件将触发时,定时器将被清除并且永远不会再次设置,那么使用它的目的是什么?


对不起我的困惑。祝你有愉快的一天。

3 个答案:

答案 0 :(得分:3)

问题1:

无论其他任何值如何,

outerPane只会被提取一次。注释掉的行将是使用此变量的位置。他的观点很简单,$(selector)多次只会重复使用结果并只调用一次。上面的代码将始终在需要它的任何地方都有outerPane变量,而且速度非常快。

问题2:

嗯,这段代码有点不对劲。我来解决它:

var timer = null;

$(window).scroll(function () {
  if (timer) {
    clearTimeout(timer);
  }

  timer = setTimeout(function() {
    timer = null; // Added this line.
    mycallback();
  }, 100);
});

关键是当用户实际停止滚动时,只执行你的大块JavaScript(在mycallback()中)。只有在100毫秒没有滚动事件发生时才会调用mycallback()

因此,当滚动发生时,首先检查是否存在未激活的超时,以及是否取消它。如果多个滚动事件发生的间隔小于100毫秒,则会发生这种情况。然后它设置一个新的计时器,从现在开始100ms,这将清除timer并点燃mycallback()

这可以防止mycallback()运行,直到100ms内没有滚动事件发生。优点是,如果mycallback()需要很长时间,它将永远不会中断浏览器的平滑滚动。

然而,在Twitter(如Resig解释)的情况下,这种方法不起作用。在Twitter的情况下,他们需要在每个滚动事件的屏幕上移动东西,因为他们在滚动时重新定位屏幕上的内容。因此,每次触发滚动事件时,他们都需要进行计算,以便在向下滚动时保持窗口正确。但是当你这样做时,你必须确保你的JS超级快,因为它会在用户滚动时反复执行多次(因此jQuery元素缓存的解释)。

答案 1 :(得分:0)

@问题2:

代码if (timer) { clearTimeout(timer); }很容易被误解,因为在我看来,使用的语法是错误的。我认为代码必须如下:

if (timer != null) { clearTimeout(timer); }

因为在clearTimeout之后,将清除变量'timer'。如果你想在'clearTimeout()'之后做alert(timer);,你可以试试。

答案 2 :(得分:0)

@问题1:

我阅读了您的相关链接,我认为您的问题的答案是if ( didScroll ) {。此查询可防止您的代码始终执行,即使不是必需的。但我不确定是100%。