I was reading John resig's blogpost: http://ejohn.org/blog/learning-from-twitter/ and I did not understand the problem with setTimeOut() there.
Question 1:
Johh shared this code:
var outerPane = $details.find(".details-pane-outer"),
didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
开发者_Python百科if ( didScroll ) {
didScroll = false;
// Check your page position and then
// Load in more results
}
}, 250);
Where is caching used here? I assume when didScroll is true, then outerPane variable will be used instead of re-searching the DOM, am I right?
Question 2:
In the comment section Michael shared a code:
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);
});
and said: "Instead of setting up an interval, the callback is only ever fired when it needs to be. Saves a few extra calls to the callback, and any overhead from the extra logic inside the scroll handler should be fairly minimal."
My question is: setTimeOut() will return a timerID which will be used by clearTimeOut to clear. Now with this setTimeout(myCallback, 100) function after every 100 mili second myCallBack function will be used, isn't it? Moreover, when the scroll event will fire the timer will be cleared and never set again, so what is the purpose of using it?
Sorry for my confusions. Have a nice day.
Question 1:
outerPane
is only ever fetched once, regardless of any other value. The commented out lines would be where this variable would be used. His point is simply that $(selector)
multiple times will always be slower just reusing the result and calling that only once. The code above will always have the outerPane
variable anywhere that needs it, and it will be super fast.
Question 2:
Well, this code is kind of wrong. Let me fix it:
var timer = null;
$(window).scroll(function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function() {
timer = null; // Added this line.
mycallback();
}, 100);
});
The point of this is to only execute your big chunk of JavaScript (in mycallback()
) when the user has actually stopped scrolling. mycallback()
will only get called when no scroll events have happened for 100ms.
So when a scroll happens, first it checks to see if there is a an unfired timeout, and if there is cancel it. This will happen if multiple scroll events happen less than 100ms apart. Then it sets a new timer to fire 100ms from now, which will clear out timer
and fire mycallback()
.
This prevents mycallback()
from running until no scroll events happen for 100ms. The advantage is that if mycallback()
takes a long time, it will never interrupt the smooth scrolling of the browser.
However, in the case of Twitter (like Resig is explaining) this approach won't work. In Twitter's case they need to move things around the screen on every scroll event because they reposition things on the screen as you scroll. So they do need to that calculation every single time the scroll event is fired in order to keep the window looking right as you scroll down. But also when you it this way, you have to make sure your JS is super fast because it will be executed many times over and over while the user scrolls around (Hence the explanation of jQuery element caching).
@ Question 2:
The code if (timer) { clearTimeout(timer); }
is easy to missunderstand, because the used syntax, in my humble opinion, is wrong. I think the code must be as follows below:
if (timer != null) { clearTimeout(timer); }
because after a clearTimeout, the variable 'timer' will be cleaned. You can try it if you would made an alert(timer);
after 'clearTimeout()'.
@ Question 1:
I read your related link and I think the answer to your question is if ( didScroll ) {
. This query prevents that your code will be executed all time, even if it is not necessary. But I'm not sure to 100%.
精彩评论