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

原文地址:https://www.cnblogs.com/yangjunhua/p/3481899.html