miniclock.js 6.17 KB
/*
 * MiniClock Count Down
 * Recode in 2014/12/23
 * By van
 */

define( 'miniclock' ,function( require, exports, module ){
    miniclock = function( target, options ){
        this.target = target;
        this.o = {
            interval : 1000  //始终运行间隔,正常显示为一秒。
            ,time : 60  //时钟最大时间值
            ,minTime : 0  //始终最小时间值
            ,type    : ['plus','minus']
            ,yourType: 'minus'  //时钟运行方式,归属于type函数中类型。
            ,SD: "发送验证码"
            ,WT: "秒后可重新发送" 
            ,mark: "s-waiting"  //标志已点击按钮。
            ,ban: "bangrey"  //已点击标志禁用样式名称。
            ,waitByDay: false  //计时器以天数为基数运作。 
            ,callback: function(){}
            ,isAuto: true //计时器是否自动开始 true -< 自动, false -< 手动
        }

        this.o = $.extend( this.o, options );
        this.o.isAuto ? this.init() : 0;
    };

    miniclock.prototype = {
        init: function(){
            /*
             * Initable All variable function.
             * And without the mark ClassName 
             * start the counter clock or not.
             */

            //激活基数计时单位为天。
            if ( this.o.waitByDay ){

                this.counterDay( this.o.waitByDay );
                
            };

            //若定时器在运作,则不再产生新的定时器。
            if ( $( this.target ).hasClass( this.o.mark ) ){ return false };

            var classname = this.o.mark+ " " +this.o.ban;

            this.clock = this.recycle( this.router()  );
        },
        start: function(){
          this.init();
        },
        router: function(){
            /*
             * Follow the type and run the function.
             */
            var _this = this, 
                format,
                number,
                classname = this.o.mark+ " " +this.o.ban,
                type = _this.o.type,
                yourType = _this.o.yourType;

            if ( _this.o.waitByDay ){
                format = timeFormat;
            }else {
                format = function( e ){
                    return e;
                };
            }

            return this.action( this.o.yourType, function( cache ){
                if ( _this.o.minTime <cache && cache< _this.o.time ){
                    number = format( cache );
                    //当临时计数值在(min,max)中时更新计数容器。
                    $( _this.target ).addClass( classname ).html( number +_this.o.WT );
                }else{
                    //重置计数器状态,初始显示文字,临时计数值,定时器等。
                    $( _this.target ).html( _this.o.SD ).removeClass( classname );
                    if ( isin( type, yourType ) ){
                        if ( yourType == "minus" ){
                            cache = _this.o.time;
                        }else {
                            cache = _this.o.minTime;
                        }
                    }
                    clearInterval( _this.clock );
                    _this.o.callback();
                };
            } );
        },
        action: function( exp, callback ){
            /*
             * Make one action like plus or minus
             * {, times, divide and so on}.
             * Feather in {} is't needed now.
             */
            var _this = this,
                mincache = this.o.minTime +1,
                maxcache = this.o.time -1;

            switch( exp ){
                case 'plus':
                    return function(){
                        callback( mincache );
                        return ++mincache;
                    };
                    break;
                case 'minus':
                    return function(){
                        callback( maxcache );
                        return --maxcache;
                    };
                    break;
            };
        },
        recycle: function( callback ){
            /*
             * Return a recycle counter.
             */
            var _this = this;

            return setInterval( callback, _this.o.interval );
        },
        counterDay: function( day ){
            /*
             * @param {number}
             * @return {false}
             * Count down by Day.
             */
            var _this = this;

           if ( day ){

                _this.o.SD = "0<span>天</span> 00:00:00";
                _this.o.WT = "";
                
            }else {
                throw Error( day+ " is not a number or positive number." );
            };

        },
        reset: function(number, fn){
          var _this = this;
          var classname = this.o.mark+ " " +this.o.ban;

          setTimeout( function(){
            $( _this.target ).html( _this.o.SD ).removeClass( classname );
            clearInterval(_this.clock);
            typeof fn == 'function' ? fn() : 0;
          }, number * 1000 );
        }
    };

    function detect( object, exp ){
        //Return number represent the exp in string or not(0<, -1=).
        return object.constructor.toString().indexOf( exp );
    };
    function isin( arr, data ){
        //Check the data whether in arr or not,
        //and then return true or false.
        for ( var each in arr ){
            if ( arr[each] === data ){
                return true;
            };
        };

        return false;
    };
    function timeFormat( number ){
        /* 
         * @param {number}
         * @return {00:00:00}
         */
        var day, hour, minute, second;

        day = parseInt( number/86400 );
        
        hour = parseInt( number/3600 );
        while( hour >= 24 ){
            hour -= 24;
        };

        minute = parseInt( number/60 );
        while( minute >= 60 ){
            minute -= 60;
        };

        second = parseInt( number%60 );

        return day 
                + "<span>天</span>" + 
                (hour < 10 ? "0"+hour : hour)
                +":"+ 
                (minute < 10 ? "0"+minute : minute)
                +":"+ 
                (second < 10 ? "0"+second : second);

    }

    return miniclock;
});