我正在阅读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函数,不是吗?此外,当滚动事件将触发时,定时器将被清除并且永远不会再次设置,那么使用它的目的是什么?
对不起我的困惑。祝你有愉快的一天。
答案 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%。