一、前言
前言:最近聖誕節來臨,需要在頁面上應用一個雪花飄落的效果,做之前產品經理給了我網絡上的一個demo,地址是
http://demo.lanrenzhijia.com/demo/1225/sd/,預覽了一下,效果不錯,但是性能可以再優化,源碼中使用setInterval重復定時器,
dom在不停地插入移除,這里主要優化這兩個地方,使用setTimeout替換setInterval,減少頁面dom的重排,其他地方可以自己調整。
二、應用實例demo
/** * component: jQuery.snowflake 2013/12/19 華子yjh * invoking: jQuery.snowflake(options) * // 配置對象 options = { length: 26, // 數量 interval: 1000, // 雪花之間出現的時間間隔 duration: 24000 // 雪花的動畫時間 } * */
demo地址1:http://miiee.taobao.com/activity/shengdan.htm
demo地址2:http://miiee.taobao.com/
三、設計思路
第一步:
用HTML實體代表雪花外形,雪花出現的位置,大小都是隨機的
第二步:
保持相鄰雪花之間出現的時間間隔(或者它們之間的距離)永遠一致; 就必須使用重復定時器,使用雙setTimeout,而非setInterval,這一步很重要
setTimeout(function call() { // do something setTimeout(call, interval); },0); // 使用雙setTimeout模擬重復定時器對於對於自動輪播等其他應用非常有用, // 推薦閱讀javascript高級程序設計一書有關setInterval的缺點及解決辦法
四、組件源碼
最初代碼:
$.extend({ // 雪花飄落組件 snowflake: function(options) { var flakeHtmlStr = '', config = { length: 26, // 數量 interval: 1000, // 雪花之間出現的時間間隔 duration: 24000 // 雪花的動畫時間 }; $.extend(config, options || {}); var len = config.length, $win = $(window), win_width = $win.width(), win_height = $win.height(), timeoutId = null, $items, i, initStyle = { position: 'absolute', top: '-50px', zIndex: 9999, opacity: 1, fontSize: 0, color: '#FFF' }, endStyle = { top: win_height + 50 + 'px', opacity: 0 }; // 插入DOM,並初始化其樣式 for (i = 0; i < len; i++) { flakeHtmlStr += '<div class="snow-flake">❄</div>'; } $(flakeHtmlStr).appendTo('body'); $items = $('.snow-flake').css(initStyle).wrapAll('<div id="snowflake-box"></div>'); // 處理單個雪花 function handleItem(idx) { var $itm = $items.eq(idx).css(initStyle), w, val; $itm.css({ fontSize: 20 + Math.ceil(Math.random() * 30, 10) + 'px' }); w = $itm.width(); val = Math.floor(Math.random() * win_width); if ((val + w) >= win_width) { val = val - w; } $itm.css({ left: val + 'px' }) .animate(endStyle, config.duration); } // 開始運行 function running() { var i = 0; setTimeout(function call() { handleItem(i); if (i < len-1) { i++; } else { i = 0; } setTimeout(call, config.interval); }, 0); } running(); } }); $.snowflake(); // 調用
更新優化后的代碼:
$.extend({ // 雪花飄落組件 snowflake: function(options) { var $items, len, win_height = $(window).height(), maxVal = $(window).width() - 24, // 防止瀏覽器出現橫向滾動條,24px為font-size: 35px;時的寬度 options = $.extend({ length: 21, // 數量 interval: 1200, // 雪花之間出現的時間間隔 duration: 24000 // 雪花的動畫時間 }, options || {}); len = options.length; // 初始化dom (function(){ var flakeHtmlStr = '', i; // 插入DOM,並初始化其樣式 for (i = 0; i < len; i++) { flakeHtmlStr += '<div class="snow-flake">❄</div>'; } $(flakeHtmlStr).appendTo('body'); $items = $('.snow-flake').css({ position: 'absolute', top: '-40px', color: '#FFF', zIndex: 999 }).wrapAll('<div id="snowflake-box"></div>'); }()); // 處理單個雪花 function handleItem(idx) { $items.eq(idx) .css({ top: '-40px', opacity: 1, left: Math.random() * maxVal + 'px', fontSize: [25, 30, 35][(Math.random() * 3).toString().charAt(0)] + 'px' }) .animate({ top: win_height + 'px', opacity: 0 }, options.duration); } // 開始運行 function running() { var i = 0; setTimeout(function call() { handleItem(i); if (i < len-1) { i++; } else { i = 0; } setTimeout(call, options.interval); }, 0); } running(); } }); $.snowflake(); // 調用
轉載請注明出處:博客園華子yjh
