jQuery.snowflake雪花飄落插件


一、前言

前言:最近聖誕節來臨,需要在頁面上應用一個雪花飄落的效果,做之前產品經理給了我網絡上的一個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">&#10052;</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(); // 調用
View Code

更新優化后的代碼:

$.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">&#10052;</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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM