Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Javascript¸ßÐÔÄܶ¯»­ÓëÒ³ÃæäÖȾ
 
»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-10-15
  2248  次浏览      27
 

No setTimeout, No setInterval

Èç¹ûÄã²»µÃ²»Ê¹ÓÃsetTimeout»òÕßsetIntervalÀ´ÊµÏÖ¶¯»­£¬ÄÇôԭÒòÖ»ÄÜÊÇÄãÐèÒª¾«È·µÄ¿ØÖƶ¯»­¡£µ«ÎÒÈÏΪÖÁÉÙÔÚÏÖÔÚÕâ¸öʱ¼äµã£¬¸ß¼¶ä¯ÀÀÆ÷¡¢ÉõÖÁÊÖ»úä¯ÀÀÆ÷µÄÆÕ¼°³Ì¶È×ã¹»ÈÃÄãÓÐÀíÓÉÓÐÌõ¼þÔÚʵÏÖ¶¯»­Ê±Ê¹Óøü¸ßЧµÄ·½Ê½¡£

ʲôÊǸßЧ

Ò³ÃæÊÇÿһ֡±ä»¯¶¼ÊÇϵͳ»æÖƳöÀ´µÄ(GPU»òÕßCPU)¡£µ«ÕâÖÖ»æÖÆÓÖºÍPCÓÎÏ·µÄ»æÖƲ»Í¬£¬ËüµÄ×î¸ß»æÖÆÆµÂÊÊÜÏÞÓÚÏÔʾÆ÷µÄË¢ÐÂÆµÂÊ(¶ø·ÇÏÔ¿¨)£¬ËùÒÔ´ó¶àÊýÇé¿öÏÂ×î¸ßµÄ»æÖÆÆµÂÊÖ»ÄÜÊÇÿÃë60Ö¡(frame per second£¬ÒÔÏÂÓÃfps¼ò³Æ)£¬¶ÔÓ¦ÓÚÏÔʾÆ÷µÄ60Hz¡£60fpsÊÇÒ»¸ö×îÀíÏëµÄ״̬£¬ÔÚÈÕ³£¶ÔÒ³ÃæÐÔÄܵIJâÊÔÖУ¬60fpsÒ²ÊÇÒ»¸öÖØÒªµÄÖ¸±ê£¬the closer the better¡£ÔÚChromeµÄµ÷ÊÔ¹¤¾ßÖУ¬Óв»ÉÙ¹¤¾ß¶¼ÊÇÓÃÓÚºâÁ¿µ±Ç°Ö¡Êý£º

½ÓÏÂÀ´µÄ¹¤×÷ÖУ¬ÎÒÃǽ«»áÓõ½ÕâЩ¹¤¾ß£¬À´ÊµÊ±²é¿´ÎÒÃÇÒ³ÃæµÄÐÔÄÜ¡£

60fpsÊǶ¯Á¦Ò²ÊÇѹÁ¦£¬ÒòΪËüÒâζ×ÅÎÒÃÇÖ»ÓÐ16.7ºÁÃë(1000 / 60)À´»æÖÆÃ¿Ò»Ö¡¡£Èç¹ûʹÓÃsetTimeout»òÕßsetInterval(ÒÔÏÂͳ³ÆÎªtimer)À´¿ØÖÆ»æÖÆ£¬ÎÊÌâ¾ÍÀ´ÁË¡£

Ê×ÏÈ£¬Timer¼ÆËãÑÓʱµÄ¾«È·¶È²»¹»¡£ÑÓʱµÄ¼ÆËãÒÀ¿¿µÄÊÇä¯ÀÀÆ÷µÄÄÚÖÃʱÖÓ£¬¶øÊ±Öӵľ«È·¶ÈÓÖÈ¡¾öÓÚʱÖÓ¸üÐÂµÄÆµÂÊ(Timer resolution)¡£IE8¼°Æä֮ǰµÄIE°æ±¾¸üмä¸ôΪ15.6ºÁÃë¡£¼ÙÉèÄãÉ趨µÄsetTimeoutÑÓ³ÙΪ16.7ms£¬ÄÇôËüÒª¸üÐÂÁ½¸ö15.6ºÁÃë²Å»á¸Ã´¥·¢ÑÓʱ¡£ÕâÒ²Òâζ×ÅÎÞ¹ÊÑÓ³ÙÁË 15.6 x 2 - 16.7 = 14.5ºÁÃë¡£

          16.7ms
DELAY: |------------|

CLOCK: |----------|----------|
15.6ms 15.6ms

ËùÒÔ¼´Ê¹Äã¸øsetTimeoutÉ趨µÄÑÓʱΪ0ms£¬ËüÒ²²»»áÁ¢¼´´¥·¢¡£Ä¿Ç°ChromeÓëIE9+ä¯ÀÀÆ÷µÄ¸üÐÂÆµÂʶ¼Îª4ms(Èç¹ûÄãʹÓõÄÊDZʼDZ¾µçÄÔ£¬²¢ÇÒÔÚʹÓÃµç³Ø¶ø·ÇµçÔ´µÄģʽÏ£¬ÎªÁ˽ÚÊ¡×ÊÔ´£¬ä¯ÀÀÆ÷»á½«¸üÐÂÆµÂÊÇл»ÖÁÓÚϵͳʱ¼äÏàͬ£¬Ò²¾ÍÒâζןüÐÂÆµÂʸüµÍ)¡£

ÍËÒ»²½Ëµ£¬¼Ùʹtimer resolutionÄܹ»´ïµ½16.7ms£¬Ëü»¹ÒªÃæÁÙÒ»¸öÒì²½¶ÓÁеÄÎÊÌâ¡£ÒòΪÒì²½µÄ¹ØÏµsetTimeoutÖеĻص÷º¯Êý²¢·ÇÁ¢¼´Ö´ÐУ¬¶øÊÇÐèÒª¼ÓÈëµÈ´ý¶ÓÁÐÖС£µ«ÎÊÌâÊÇ£¬Èç¹ûÔڵȴýÑÓ³Ù´¥·¢µÄ¹ý³ÌÖУ¬ÓÐеÄͬ²½½Å±¾ÐèÒªÖ´ÐУ¬ÄÇôͬ²½½Å±¾²»»áÅÅÔÚtimerµÄ»Øµ÷Ö®ºó£¬¶øÊÇÁ¢¼´Ö´ÐУ¬±ÈÈçÏÂÃæÕâ¶Î´úÂ룺

function runForSeconds(s) {
var start = +new Date();
while (start + s * 1000 > (+new Date())) {}
}

document.body.addEventListener("click", function () {
runForSeconds(10);
}, false);

setTimeout(function () {
console.log("Done!");
}, 1000 * 3);

Èç¹ûÔڵȴý´¥·¢ÑÓ³ÙµÄ3Ãë¹ý³ÌÖУ¬ÓÐÈ˵ã»÷ÁËbody£¬ÄÇô»Øµ÷»¹ÊÇ׼ʱÔÚ3sÍê³Éʱ´¥·¢Â𣿵±È»²»ÄÜ£¬Ëü»áµÈ´ý10s£¬Í¬²½º¯Êý×ÜÊÇÓÅÏÈÓÚÒì²½º¯Êý£º

µÈ´ý3ÃëÑÓ³Ù |    1s    |    2s    |    3s    |--->console.log("Done!");

¾­¹ý2Ãë |----1s----|----2s----| |--->console.log("Done!");

µã»÷bodyºó

ÒÔΪÊÇÕâÑù£º|----1s----|----2s----|----3s----|--->console.log("Done!")--->|------------------10s----------------|

ÆäʵÊÇÕâÑù£º|----1s----|----2s----|------------------10s----------------|--->console.log("Done!");

John ResignÓÐÈýƪ¹ØÓÚTimerÐÔÄÜÓë׼ȷÐÔµÄÎÄÕÂ: 1.Accuracy of JavaScript Time, 2.Analyzing Timer Performance£¬ 3.How JavaScript Timers Work¡£´ÓÎÄÕÂÖпÉÒÔ¿´µ½TimerÔÚ²»Í¬Æ½Ì¨ä¯ÀÀÆ÷Óë²Ù×÷ϵͳϵÄһЩÎÊÌâ¡£

ÔÙÍËÒ»²½Ëµ£¬¼ÙÉètimer resolutionÄܹ»´ïµ½16.7ms£¬²¢ÇÒ¼ÙÉèÒì²½º¯Êý²»»á±»ÑÓºó£¬Ê¹ÓÃtimer¿ØÖƵ͝»­»¹ÊÇÓв»¾¡ÈçÈËÒâµÄµØ·½¡£ÕâÒ²¾ÍÊÇÏÂÒ»½ÚҪ˵µÄÎÊÌâ¡£

´¹Ö±Í¬²½ÎÊÌâ

ÕâÀïÇëÔÙÔÊÐíÎÒÒýÈëÁíÒ»¸ö³£Á¿60¡ª¡ªÆÁÄ»µÄË¢ÐÂÂÊ60Hz¡£

60HzºÍ60fpsÓÐʲô¹ØÏµ£¿Ã»ÓÐÈκιØÏµ¡£fps´ú±íGPUäÖȾ»­ÃæµÄƵÂÊ£¬Hz´ú±íÏÔʾÆ÷Ë¢ÐÂÆÁÄ»µÄƵÂÊ¡£Ò»·ù¾²Ì¬Í¼Æ¬£¬Äã¿ÉÒÔ˵Õ⸱ͼƬµÄfpsÊÇ0Ö¡/Ã룬µ«¾ø¶Ô²»ÄÜ˵´ËʱÆÁÄ»µÄË¢ÐÂÂÊÊÇ0Hz£¬Ò²¾ÍÊÇ˵ˢÐÂÂʲ»ËæÍ¼ÏñÄÚÈݵı仯¶ø±ä»¯¡£ÓÎÏ·Ò²ºÃä¯ÀÀÆ÷Ò²ºÃ£¬ÎÒÃÇ̸µ½µôÖ¡£¬ÊÇÖ¸GPUäÖȾ»­ÃæÆµÂʽµµÍ¡£±ÈÈçµøÂäµ½30fpsÉõÖÁ20fps£¬µ«ÒòΪÊÓ¾õÔÝÁôÔ­Àí£¬ÎÒÃÇ¿´µ½µÄ»­ÃæÈÔÈ»ÊÇÔ˶¯ºÍÁ¬¹áµÄ¡£

½ÓÉÏÒ»½Ú£¬ÎÒÃǼÙÉèÿһ´Îtimer¶¼²»»áÓÐÑÓʱ£¬Ò²²»»á±»Í¬²½º¯Êý¸ÉÈÅ£¬ÉõÖÁÄܰÑʱ¼äËõ¶ÌÖÁ16ms£¬ÄÇô»á·¢ÉúÊ²Ã´ÄØ£º

ÔÚ22Ãë´¦·¢ÉúÁ˶ªÖ¡

Èç¹û°ÑÑÓ³Ùʱ¼äËõµÄ¸ü¶Ì£¬¶ªÊ§µÄÖ¡ÊýÒ²¾Í¸ü¶à£º

ʵ¼ÊÇé¿ö»á±ÈÒÔÉÏÏëÏóµÄ¸´ÔӵĶࡣ¼´Ê¹ÄãÄܸø³öÒ»¸ö¹Ì¶¨µÄÑÓʱ£¬½â¾ö60HzÆÁĻ϶ªÖ¡ÎÊÌ⣬ÄÇôÆäËûË¢ÐÂÆµÂʵÄÏÔʾÆ÷Ó¦¸ÃÔõô°ì£¬ÒªÖªµÀ²»Í¬É豸¡¢ÉõÖÁÏàͬÉ豸ÔÚ²»Í¬µç³Ø×´Ì¬ÏÂµÄÆÁĻˢÐÂÂʶ¼²»¾¡Ïàͬ¡£

ÒÔÉÏͬʱ»¹ºöÂÔÁËÆÁĻˢл­ÃæµÄʱ¼ä³É±¾¡£ÎÊÌâ²úÉúÓÚGPUäÖȾ»­ÃæµÄƵÂÊºÍÆÁĻˢÐÂÆµÂʵIJ»Ò»Ö£ºÈç¹ûGPUäÖȾ³öÒ»Ö¡»­ÃæµÄʱ¼ä±ÈÏÔʾÆ÷Ë¢ÐÂÒ»ÕÅ»­ÃæµÄʱ¼äÒª¶Ì(¸ü¿ì)£¬ÄÇôµ±ÏÔʾÆ÷»¹Ã»ÓÐË¢ÐÂÍêÒ»ÕÅͼƬʱ£¬GPUäÖȾ³öµÄÁíÒ»ÕÅͼƬÒѾ­ËÍ´ï²¢¸²¸ÇÁËǰһÕÅ£¬µ¼ÖÂÆÁÄ»ÉÏ»­ÃæµÄ˺ÁÑ£¬Ò²¾ÍÊÇÊÇÉϰ벿·ÖÊÇǰһÕÅͼƬ£¬Ï°벿·ÖÊǺóÒ»ÕÅͼƬ£º

PCÓÎÏ·Öнâ¾öÕâ¸öÎÊÌâµÄ·½·¨ÊÇ¿ªÆô´¹Ö±Í¬²½(v-sync)£¬Ò²¾ÍÊÇÈÃGPUÍ×Э£¬GPUäÖȾͼƬ±ØÐëÔÚÆÁÄ»Á½´ÎË¢ÐÂÖ®¼ä£¬ÇÒ±ØÐëµÈ´ýÆÁÄ»·¢³öµÄ´¹Ö±Í¬²½Ðźš£µ«ÕâÑùͬÑùÒ²ÊÇÒª¸¶³ö´ú¼ÛµÄ£º½µµÍÁËGPUµÄÊä³öƵÂÊ£¬Ò²¾Í½µµÍÁË»­ÃæµÄÖ¡Êý¡£ÒÔÖÁÓÚÄãÔÚÍæÐèÒª¸ßÖ¡ÊýÔËÐеÄÓÎϷʱ(±ÈÈ羺ËÙ¡¢µÚÒ»È˳ÆÉä»÷)¸Ð¾õµ½¡°¶Ù¿¨¡±£¬ÒòΪµôÖ¡¡£

requestAnimationFrame

ÔÚÕâÀﲻ̸requestAnimationFrame(ÒÔϼò³ÆrAF)Ó÷¨£¬¾ßÌåÇë²Î¿¼MDN:Window.requestAnimationFrame()¡£ÎÒÃÇÀ´¾ßÌå̸̸rAFËù½â¾öµÄÎÊÌâ¡£

´ÓÉÏÒ»½ÚÎÒÃÇ¿ÉÒÔ×ܽá³öʵÏÖÆ½»¬¶¯»­µÄÁ½¸öÒòËØ

1.ʱ»ú(Frame Timing)£º еÄÒ»Ö¡×¼±¸ºÃµÄʱ»ú

2.³É±¾(Frame Budget)£º äÖȾеÄÒ»Ö¡ÐèÒª¶à³¤µÄʱ¼ä

Õâ¸öNative API°ÑÎÒÃÇ´Ó¾À½áÓÚ¶à¾ÃˢеÄÒ»´ÎµÄÀ§¾³Öнâ¾È³öÀ´(ÆäʵrAFÒ²²»¹ØÐľàÀëÏÂ´ÎÆÁĻˢÐÂÒ³Ãæ»¹ÐèÒª¶à¾Ã)¡£µ±ÎÒÃǵ÷ÓÃÕâ¸öº¯ÊýµÄʱºò£¬ÎÒÃǸæËßËüÐèÒª×öÁ½¼þÊ£º 1. ÎÒÃÇÐèҪеÄÒ»Ö¡£»2.µ±ÄãäÖȾеÄһ֡ʱÐèÒªÖ´ÐÐÎÒ´«¸øÄãµÄ»Øµ÷º¯Êý

ÄÇôËü½â¾öÁËÎÒÃÇÉÏÃæÃèÊöµÄµÚÒ»¸öÎÊÌ⣬²úÉúеÄÒ»Ö¡µÄʱ»ú¡£

ÄÇôµÚ¶þ¸öÎÊÌâÄØ¡£²»£¬ËüÎÞÄÜΪÁ¦¡£±ÈÈç¿ÉÒÔ¶Ô±ÈÏÂÃæÁ½¸öÒ³Ãæ£º

DEMO
DEMO-FIXED

¶Ô±ÈÁ½¸öÒ³ÃæµÄÔ´Â룬Äã»á·¢ÏÖÖ»ÓÐÒ»´¦²»Í¬£º

// animation loop
function update(timestamp) {
for(var m = 0; m < movers.length; m++) {
// DEMO °æ±¾
//movers[m].style.left = ((Math.sin(movers[m].offsetTop + timestamp/1000)+1) * 500) + 'px';

// FIXED °æ±¾
movers[m].style.left = ((Math.sin(m + timestamp/1000)+1) * 500) + 'px';
}
rAF(update);
};
rAF(update);

DEMO°æ±¾Ö®ËùÒÔÂýµÄÔ­ÒòÊÇ£¬ÔÚÐÞ¸Äÿһ¸öÎïÌåµÄleftֵʱ£¬»áÇëÇóÕâ¸öÎïÌåµÄoffsetTopÖµ¡£ÕâÊÇÒ»¸ö·Ç³£ºÄʱµÄreflow²Ù×÷(¾ßÌ廹ÓÐÄÄЩºÄʱµÄreflow²Ù×÷¿ÉÒԲο¼ÕâÆª:How (not) to trigger a layout in WebKit)¡£ÕâÒ»µã´ÓChromeµ÷ÊÔ¹¤¾ßÖпÉÒÔ¿´³öÀ´(½ØÍ¼ÖеÄijЩ¹¦ÄÜÐèÒªÔÚChrome canary°æ±¾ÖÐ²Å¿ÉÆôÓÃ)

δ½ÃÕýµÄ°æ±¾

¿É¼û´ó²¿·Öʱ¼ä¶¼»¨ÔÚÁËrenderingÉÏ£¬¶ø½ÃÕýÖ®ºóµÄ°æ±¾£º

renderingʱ¼ä´ó´ó¼õÉÙÁË

µ«Èç¹ûÄãµÄ»Øµ÷º¯ÊýºÄÊ±ÕæµÄºÜÑÏÖØ£¬rAF»¹ÊÇ¿ÉÒÔΪÄã×öһЩʲôµÄ¡£±ÈÈçµ±Ëü·¢ÏÖÎÞ·¨Î¬³Ö60fpsµÄƵÂÊʱ£¬Ëü»á°ÑƵÂʽµµÍµ½30fps£¬ÖÁÉÙÄܹ»±£³ÖÖ¡ÊýµÄÎȶ¨£¬±£³Ö¶¯»­µÄÁ¬¹á¡£

ʹÓÃrAFÍÆ³Ù´úÂë

ûÓÐʲôÊÇÍòÄܵģ¬Ãæ¶ÔÉÏÃæµÄÇé¿ö£¬ÎÒÃÇÐèÒª¶Ô´úÂë½øÐÐ×éÖ¯ºÍÓÅ»¯¡£

¿´¿´ÏÂÃæÕâÑùÒ»¶Î´úÂ룺

function jank(second) {
var start = +new Date();
while (start + second * 1000 > (+new Date())) {}
}

div.style.backgroundColor = "red";

// some long run task
jank(5);

div.style.backgroundColor = "blue";

ÎÞÂÛÔÚÈκεÄä¯ÀÀÆ÷ÖÐÔËÐÐÉÏÃæµÄ´úÂ룬Äã¶¼²»»á¿´µ½div±äΪºìÉ«£¬Ò³ÃæÍ¨³£»áÔÚ¼ÙËÀ5Ã룬ȻºóÈÝÆ÷±äΪÀ¶É«¡£ÕâÊÇÒòΪä¯ÀÀÆ÷µÄʼÖÕÖ»ÓÐÒ»¸öÏß³ÌÔÚÔËÐÐ(¿ÉÒÔÕâôÀí½â£¬ÒòΪjsÒýÇæÓëUIÒýÇæ»¥³â)¡£ËäÈ»Äã¸æËßä¯ÀÀÆ÷´Ëʱdiv±³¾°ÑÕɫӦ¸ÃΪºìÉ«£¬µ«ÊÇËü´Ëʱ»¹ÔÚÖ´Ðнű¾£¬ÎÞ·¨µ÷ÓÃUIÏ̡߳£

ÓÐÁËÕâ¸öǰÌᣬÎÒÃǽÓÏÂÀ´¿´Õâ¶Î´úÂ룺

var div = document.getElementById("foo");

var currentWidth = div.innerWidth;
div.style.backgroundColor = "blue";

// do some "long running" task, like sorting data

Õâ¸öʱºòÎÒÃDz»½ö½öÐèÒª¸üб³¾°ÑÕÉ«£¬»¹ÐèÒª»ñÈ¡ÈÝÆ÷µÄ¿í¶È¡£¿ÉÒÔÏëÏóËüµÄÖ´ÐÐ˳ÐòÈçÏ£º

µ±ÎÒÃÇÇëÇóinnerWidthÒ»ÀàµÄÊôÐÔʱ£¬ä¯ÀÀÆ÷»áÒÔΪÎÒÃÇÂíÉÏÐèÒª£¬ÓÚÊÇËü»áÁ¢¼´¸üÐÂÈÝÆ÷µÄÑùʽ(ͨ³£ä¯ÀÀÆ÷»áÔÜ×ÅÒ»Åú£¬µÈ´ýʱ»úÒ»´ÎÐÔµÄrepaint£¬ÒÔ±ã½ÚÊ¡ÐÔÄÜ)£¬²¢°Ñ¼ÆËãµÄ½á¹û¸æËßÎÒÃÇ¡£Õâͨ³£ÊÇÐÔÄÜÏûºÄÁ¿´óµÄ¹¤×÷¡£

µ«Èç¹ûÎÒÃDz¢·ÇÁ¢¼´ÐèÒªµÃµ½½á¹ûÄØ£¿

ÉÏÃæµÄ´úÂëÓÐÁ½´¦²»×㣬

¸üб³¾°ÑÕÉ«µÄ´úÂë¹ýÓÚÌáǰ£¬¸ù¾Ýǰһ¸öÀý×Ó£¬ÎÒÃÇÖªµÀ£¬¼´Ê¹ÔÚÕâÀï¸æÖªÁËä¯ÀÀÆ÷ÎÒÐèÒª¸üб³¾°ÑÕÉ«£¬ä¯ÀÀÆ÷ÖÁÉÙÒ²ÒªµÈµ½jsÔËÐÐÍê±Ï²ÅÄܵ÷ÓÃUIỊ̈߳»

¼ÙÉèºóÃæ²¿·ÖµÄlong runing´úÂë»áÆô¶¯Ò»Ð©Òì²½´úÂ룬±ÈÈçsetTimeout»òÕßAjaxÇëÇóÓÖ»òÕßweb-worker£¬ÄÇÓ¦¸Ã¾¡ÔçΪÃî¡£

×ÛÉÏËùÊö£¬Èç¹ûÎÒÃDz»ÊÇÄÇôÆÈÇеÄÐèÒªÖªµÀinnerWidth£¬ÎÒÃÇ¿ÉÒÔʹÓÃrAFÍÆ³ÙÕⲿ·Ö´úÂëµÄ·¢Éú£º

requestAnimationFrame(function(){
var el = document.getElementById("foo");

var currentWidth = el.innerWidth;
el.style.backgroundColor = "blue";

// ...
});

// do some "long running" task, like sorting data

¿É¼û¼´Ê¹ÎÒÃÇÔÚÕâÀïûÓÐʹÓõ½¶¯»­£¬µ«ÈÔÈ»¿ÉÒÔʹÓÃrAFÓÅ»¯ÎÒÃǵĴúÂë¡£Ö´ÐеÄ˳Ðò»á±ä³É£º

ÔÚÕâÀïrAFµÄÓ÷¨±ä³ÉÁË£º°Ñ´úÂëÍÆ³Ùµ½ÏÂÒ»Ö¡Ö´ÐС£

ÓÐʱºòÎÒÃÇÐèÒª°Ñ´úÂëÍÆ³ÙµÄ¸üÔ¶£¬±ÈÈçÕâ¸öÑù×Ó£º

ÔÙ±ÈÈçÎÒÃÇÏëÒªÒ»¸öЧ¹û·ÖÁ½²½Ö´ÐУº1.divµÄdisplay±äΪblock£»2. divµÄtopÖµËõ¶ÌÒÆ¶¯µ½Ä³´¦¡£Èç¹ûÕâÁ½Ïî²Ù×÷¶¼·ÅÈëͬһ֡Öеϰ£¬ä¯ÀÀÆ÷»áͬʱ°ÑÕâÁ½Ïî¸ü¸ÄÓ¦ÓÃÓÚÈÝÆ÷£¬ÔÚͬһ֡ÄÚ¡£ÓÚÊÇÎÒÃÇÐèÒªÁ½Ö¡°ÑÕâÁ½Ïî²Ù×÷Çø·Ö¿ªÀ´£º

requestAnimationFrame(function(){
el.style.display = "block";
requestAnimationFrame(function(){
// fire off a CSS transition on its `top` property
el.style.top = "300px";
});
});

ÕâÑùµÄд·¨ºÃÏñÓÐЩ²»Ì«½²¾¿£¬Kyle SimpsonÓÐÒ»¸ö¿ªÔ´ÏîÄ¿h5ive£¬Ëü°ÑÉÏÃæµÄÓ÷¨·â×°ÁËÆðÀ´£¬²¢ÇÒÌṩÁËAPI¡£ÊµÏÖÆðÀ´·Ç³£¼òµ¥£¬ÕªÒ»¶Î´úÂëÇÆÇÆ£º

function qID(){
var id;
do {
id = Math.floor(Math.random() * 1E9);
} while (id in q_ids);
return id;
}

function queue(cb) {
var qid = qID();

q_ids[qid] = rAF(function(){
delete q_ids[qid];
cb.apply(publicAPI,arguments);
});

return qid;
}

function queueAfter(cb) {
var qid;

qid = queue(function(){
// do our own rAF call here because we want to re-use the same `qid` for both frames
q_ids[qid] = rAF(function(){
delete q_ids[qid];
cb.apply(publicAPI,arguments);
});
});

return qid;
}

ʹÓ÷½·¨£º

// ²åÈëÏÂÒ»Ö¡
id1 = aFrame.queue(function(){
text = document.createTextNode("##");
body.appendChild(text);
});

// ²åÈëÏÂÏÂÒ»Ö¡
id2 = aFrame.queueAfter(function(){
text = document.createTextNode("!!");
body.appendChild(text);
});

ʹÓÃrAF½âñî´úÂë

ÏÈ´ÓÒ»¸ö2011ÄêtwitterÓöµ½µÄbug˵Æð¡£

µ±Ê±twitter¼ÓÈëÁËÒ»¸öй¦ÄÜ£º¡°ÎÞÏÞ¹ö¶¯¡±¡£Ò²¾ÍÊǵ±Ò³Ãæ¹öÖÁµ×²¿µÄʱºò£¬È¥¼ÓÔØ¸ü¶àµÄtwitter£º

$(window).bind('scroll', function () {
if (nearBottomOfPage()) {
// load more tweets ...
}
});

µ«ÊÇÔÚÕâ¸ö¹¦ÄÜÉÏÏßÖ®ºó£¬·¢ÏÖÁËÒ»¸öÑÏÖØµÄbug£º¾­¹ý¼¸´Î¹ö¶¯µ½×îµ×²¿Ö®ºó£¬¹ö¶¯¾Í»á±äµÃÆæÂýÎޱȡ£

¾­¹ýÅŲ鷢ÏÖ£¬Ô­À´ÊÇÒ»ÌõÓï¾äÒýÆðµÄ£º$details.find(".details-pane-outer");

Õ⻹²»ÊÇÕæÕýµÄ×ï¿ý»öÊ×£¬ÕæÕýµÄÔ­ÒòÊÇÒòΪËûÃǽ«Ê¹ÓõÄjQueryÀà¿â´Ó1.4.2Éý¼¶µ½ÁË1.4.4°æ¡£¶øÕâjQueryÆäÖÐÒ»¸öÖØÒªµÄÉý¼¶ÊǰÑSizzleµÄÉÏÏÂÎÄÑ¡ÔñÆ÷È«²¿Ì滻ΪÁËquerySelectorAll¡£µ«ÊÇÕâ¸ö½Ó¿ÚԭʵÏÖʹÓõÄÊÇgetElementsByClassName¡£ËäÈ»querySelectorAllÔڴ󲿷ÖÇé¿öÏÂÐÔÄÜ»¹ÊDz»´íµÄ¡£µ«ÔÚͨ¹ýClassÃû³ÆÑ¡ÔñÔªËØÕâÒ»ÏîÊÇÕ¼ÁËÏ·硣ÓÐÁ½¸ö¶Ô±È²âÊÔ¿ÉÒÔ¿´³öÀ´£º1.querySelectorAll v getElementsByClassName2.jQuery Simple Selector

ͨ¹ýÕâ¸öbug£¬John Resig¸ø³öÁËÒ»Ìõ(ʵ¼ÊÉÏÊÇÁ½Ìõ£¬µ«ÊǽñÌìֻȡÓëÎÒÃÇ»°ÌâÓйصÄ)·Ç³£ÖØÒªµÄ½¨Òé

It¡¯s a very, very, bad idea to attach handlers to the window scroll event.

ËûÏë±í´ïµÄÒâ˼ÊÇ£¬Ïñscroll£¬resizeÕâÒ»ÀàµÄʼþ»á·Ç³£Æµ·±µÄ´¥·¢£¬Èç¹û°ÑÌ«¶àµÄ´úÂë·Å½øÕâÒ»ÀàµÄ»Øµ÷º¯ÊýÖУ¬»áÑÓ³ÙÒ³ÃæµÄ¹ö¶¯£¬ÉõÖÁÔì³ÉÎÞ·¨ÏìÓ¦¡£ËùÒÔÓ¦¸Ã°ÑÕâÒ»Àà´úÂë·ÖÀë³öÀ´£¬·ÅÔÚÒ»¸ötimerÖУ¬Óмä¸ôµÄÈ¥¼ì²éÊÇ·ñ¹ö¶¯£¬ÔÙ×öÊʵ±µÄ´¦Àí¡£±ÈÈçÈçÏ´úÂ룺

var didScroll = false;

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

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

ÕâÑùµÄ×÷·¨ÀàËÆÓÚNicholas½«ÐèÒª³¤Ê±¼äÔËËãµÄÑ­»··Ö½âΪ¡°Æ¬¡±À´½øÐÐÔËË㣺

// ¾ßÌå¿ÉÒԲο¼ËûдµÄ¡¶javascript¸ß¼¶³ÌÐòÉè¼Æ¡·
// Ò²¿ÉÒԲο¼ËûµÄÕâÆª²©¿Í£º http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/
function chunk(array, process, context){
var items = array.concat(); //clone the array
setTimeout(function(){
var item = items.shift();
process.call(context, item);

if (items.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}

Ô­ÀíÆäʵÊÇÒ»ÑùµÄ£¬ÎªÁËÓÅ»¯ÐÔÄÜ¡¢ÎªÁË·ÀÖ¹ä¯ÀÀÆ÷¼ÙËÀ£¬½«ÐèÒª³¤Ê±¼äÔËÐеĴúÂë·Ö½âΪС¶ÎÖ´ÐУ¬Äܹ»Ê¹ä¯ÀÀÆ÷ÓÐʱ¼äÏìÓ¦ÆäËûµÄÇëÇó¡£

»Øµ½rAFÉÏÀ´£¬ÆäʵrAFÒ²¿ÉÒÔÍê³ÉÏàͬµÄ¹¦ÄÜ¡£±ÈÈç×î³õµÄ¹ö¶¯´úÂëÊÇÕâÑù£º

function onScroll() {
update();
}

function update() {

// assume domElements has been declared
for(var i = 0; i < domElements.length; i++) {

// read offset of DOM elements
// to determine visibility - a reflow

// then apply some CSS classes
// to the visible items - a repaint

}
}

window.addEventListener('scroll', onScroll, false);

ÕâÊǺܵäÐ͵ķ´Àý£ºÃ¿Ò»´Î¹ö¶¯¶¼ÐèÒª±éÀúËùÓÐÔªËØ£¬¶øÇÒÿһ´Î±éÀú¶¼»áÒýÆðreflowºÍrepaint¡£½ÓÏÂÀ´ÎÒÃÇÒª×öµÄÊÂÇé¾ÍÊǰÑÕâЩ·ÑʱµÄ´úÂë´ÓupdateÖнâñî³öÀ´¡£

Ê×ÏÈÎÒÃÇÈÔÈ»ÐèÒª¸øscrollʼþÌí¼Ó»Øµ÷º¯Êý£¬ÓÃÓڼǼ¹ö¶¯µÄÇé¿ö£¬ÒÔ·½±ãÆäËûº¯ÊýµÄ²éѯ£º

var latestKnownScrollY = 0;

function onScroll() {
latestKnownScrollY = window.scrollY;
}

½ÓÏÂÀ´°Ñ·ÖÀë³öÀ´µÄrepaint»òÕßreflow²Ù×÷È«²¿·ÅÈëÒ»¸öupdateº¯ÊýÖУ¬²¢ÇÒʹÓÃrAF½øÐе÷Óãº

function update() {
requestAnimationFrame(update);

var currentScrollY = latestKnownScrollY;

// read offset of DOM elements
// and compare to the currentScrollY value
// then apply some CSS classes
// to the visible items
}

// kick off
requestAnimationFrame(update);

Æäʵ½âñîµÄÄ¿µÄÒѾ­´ïµ½ÁË£¬µ«»¹ÐèÒª×öһЩÓÅ»¯£¬±ÈÈç²»ÄÜÈÃupdateÎÞÏÞÖ´ÐÐÏÂÈ¥£¬ÐèÒªÉè±ê־λÀ´¿ØÖÆËüµÄÖ´ÐУº

var latestKnownScrollY = 0,
ticking = false;

function onScroll() {
latestKnownScrollY = window.scrollY;
requestTick();
}

function requestTick() {
if(!ticking) {
requestAnimationFrame(update);
}
ticking = true;
}

²¢ÇÒÎÒÃÇʼÖÕÖ»ÐèÒªÒ»¸örAFʵÀýµÄ´æÔÚ£¬Ò²²»ÔÊÐíÎÞÏ޴εÄupdateÏÂÈ¥£¬ÓÚÊÇÎÒÃÇ»¹ÐèÒªÒ»¸ö³ö¿Ú£º

function update() {
// reset the tick so we can
// capture the next onScroll
ticking = false;

var currentScrollY = latestKnownScrollY;

// read offset of DOM elements
// and compare to the currentScrollY value
// then apply some CSS classes
// to the visible items
}

// kick off - no longer needed! Woo.
// update();

   
2248 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕ Ïà¹ØÎĵµ Ïà¹Ø¿Î³Ì



Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

AndroidÊÖ»ú¿ª·¢£¨Ò»£©
Àí½âJavascript
·ÇµäÐÍajaxʵ¼ù
³¹µ×µÄAjax
javascript ʹÓÃCookies
ʹÓà jQuery ¼ò»¯ Ajax ¿ª·¢


Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ


ijº½¿Õ¹«Ë¾IT²¿ JavaScriptʵ¼ù
ijµçÊÓÈí¼þ HTML5ºÍJavaScript
Öк½ÐÅ JavaScript¸ß¼¶Ó¦Óÿª·¢
´óÇìÓÍÌï web½çÃæAjax¿ª·¢¼¼Êõ
ºÍÀûʱ ʹÓÃAJAX½øÐÐWEBÓ¦Óÿª·¢