JS數量輸入控件


   很早看到kissy首頁 有數量輸入控件,就隨便看了下功能 感覺也不怎么難 所以也就試着自己也做了一個, 當然基本的功能和他們的一樣,只是用了自己的編碼思想來解決這么一個問題。特此給大家分享下!kissy demo鏈接 

  個人編寫的 demo鏈接

  下面來一步步分析下我當初寫代碼的思路:

   1. 首先是HTMl代碼如下:

<h3>demo1:步長為0.8,下限為0, 默認是1</h3>
<div id="demo1"></div>
<button id="s40">設為40</button>
<button id="increase">加一步</button>
<button id="decrease">減一步</button>

  而我打開控件demo頁面時候 在火狐游覽器firebug看到如下代碼:

 

也就是說 <div id="demo1"></div> 里面的span input代碼是JS自動生成的。

 2. 我JS代碼做了如下事情:

      1.  先判斷傳進來的容器類型判斷. 支持 demo1,#demo1,.demo1,$('#demo1') 這幾種容器類型的傳參數。如下代碼判斷:

/*
     * 判斷傳進來的容器參數類型
     */
    _type: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        if(_config.container != '') {

            if($.isPlainObject(_config.container)) {
            _config.container = _config.container;

            }else if(/^\./.test(_config.container)){
                _config.container = $(_config.container);

            }else if(/^#/.test(_config.container)) {
                _config.container = $(_config.container);

            }else if($('#' + _config.container)) {
                _config.container = $('#' + _config.container);

            }else {
                alert('傳參的類型有誤!請重新傳參!');
            }

        }else {
            return;
        }
    },

      2. 渲染相對應容器里面的代碼,也就是span input標簽那些HTML代碼。如下:

/*
     * 渲染html
     */
    _renderHTML: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var html = '';
        html += '<span class="'+_config.elCls+'-amount-wrap">' + 
                    '<input type="text" title="請輸入數字" value="'+_config.val+'" class="'+_config.elCls+'-amount-input"/>' +
                    '<span class="'+_config.elCls+'-amount-increase"></span>' + 
                    '<span class="'+_config.elCls+'-amount-decrease"></span>' + 
                '</span>';
        $(_config.container).append(html);
    },

  3. 綁定事件(包括點擊,↑↓鍵操作等)。

     1. 點擊下一頁按鈕 或者↑ 操作時候 調用 增加方法:increase 代碼如下:

/*
     * 增加方法 獲取input值 然后加個步長 (每次點擊時候 判斷此值是否大於maxVal)
     * @method {increase public}
     */
    increase: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;

        var inputVal = $.trim($('.' + _config.elCls + "-amount-input",_config.container).attr('value'));
        if(inputVal * 1 < _config.maxVal * 1) {
            
            var curVal = self._addFun(inputVal * 1,_config.step * 1);
            if(curVal >= _config.maxVal * 1) {
                curVal = _config.maxVal * 1;
            }
            $('.' + _config.elCls + "-amount-input",_config.container).val(curVal);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',curVal);

            // 回調
            _config.nextFunc && $.isFunction(_config.nextFunc) && _config.nextFunc({value:curVal});
        }
            
    },

     2. 點擊上一頁按鈕時候 或者 ↓鍵操作 時候 調用 decrease(減少方法)。如下代碼:

/*
     * 減少方法 獲取input值 然后減去步長 (每次點擊時候 判斷此值是否大於minVal)
     * @method {decrease public}
     */
    decrease: function() {
        var self = this,
            _config = self.config;
        var inputVal = $.trim($('.' + _config.elCls + "-amount-input",_config.container).attr('value'));
        if(inputVal * 1 > _config.minVal * 1) {
            var curVal = self._subtraction(inputVal * 1, _config.step * 1);
            if(curVal <= _config.minVal * 1) {
                curVal = _config.minVal * 1;
            }
            $('.' + _config.elCls + "-amount-input",_config.container).val(curVal);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',curVal);

            // 回調
            _config.prevFunc && $.isFunction(_config.prevFunc) && _config.prevFunc({value:curVal});
        }
    },

     3. 同樣支持在外部設置值 比如 我new一個實例后 我想點擊一個按鈕后 直接讓此到某個值上 可以直接用new出來的實例調用setVal 方法。代碼如下:

/*
     * 可以供外部直接設置值
     * @method {setVal public} 
     */
    setVal: function(val) {
        var self = this,
            _config = self.config;

        // 簡單的判斷下 此值是否是數字型的
        if(/\d/.test(val)) {
            $('.' + _config.elCls + "-amount-input",_config.container).val(val);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',val);
        }
    },

     4. 由於需求不斷的變增 所以配置項時候 步長有可能是小數 比如 點擊一下 增加0.5步長 那么在計算的時候 會有誤差(因為計算機存儲的是以2進制存儲的),那么處理這樣的方法用到了 上一篇文章  關於javascript中對浮點加,減,乘,除的精度分析 .

可配置的參數如下

container  必須,控件插入的容器 默認為空
 val  1          // input初始值 默認為1 可以根據自己配置
 step  1,        // 步長 一次改變的變化值 默認為 1
 minVal  0,       // 限下值 默認為0
 maxVal  100,   // 限上值 默認為100
 elCls  'data', // 自定義的前綴的類名 默認為data
 prevFunc   點擊上一頁按鈕 的回調函數
 nextFunc   點擊下一頁按鈕的 回調函數

下面貼下HTML代碼如下:

<h3>demo1:步長為0.8,下限為0, 默認是1</h3>
<div id="demo1"></div>
<button id="s40">設為40</button>
<button id="increase">加一步</button>
<button id="decrease">減一步</button>

CSS代碼:

.data-amount-wrap{position:relative;height:28px;display:block}
    .data-amount-input{
        color: #666;
        font-size: 12px;
        margin:0;
        padding:3px 2px 0 3px;
        height:26px;
        border:1px solid;
        border-color:#848484 #E0E0E0 #E0E0E0 #848484;
        width:60px;
        line-height:26px;
        margin-left:16px;
    }
    .data-amount-increase,.data-amount-decrease{
        position: absolute;
        /*width:16px;height: 14px;*/cursor: pointer;
        width:0;height:0;overflow:hidden;
        border-style:solid;
    }
    .data-amount-increase{left:85px;top:1px;border-width: 14px 0 14px 14px;border-color:transparent  transparent  transparent green;}
    .data-amount-decrease{left:0;top:1px;border-width: 14px 14px 14px 0;border-color:transparent red transparent  transparent ;}
    button{margin:15px 0 0;}
View Code

JS代碼如下:

/**
 * 數量輸入控件
 */

 function Amount(options) {
    
    this.config = {
        container : '',      // 必須,控件插入的容器 默認為空
        val       : 1,       // 初始值 默認為1
        step      : 1,       // 一次改變的變化值 默認為1
        minVal    : 0,       // 限下值 默認為0
        maxVal    : 100,     // 限上值 默認為100
        elCls     : 'data',  // 自定義的前綴的類名 默認為data
        prevFunc  : null,    // 點擊上一頁回調函數
        nextFunc  : null     // 點擊下一頁回調函數
    };

    this.cache = {
        decimalLen : 1  // 默認為1
    };

    this.init(options);
 }
 
 Amount.prototype = {
    
    constructor: Amount,

    init:function(options){
        
        this.config = $.extend(this.config,options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        // 先判斷傳進來的容器類型
        self._type();
        
        // 渲染HTML代碼
        self._renderHTML();
        
        // 點擊事件
        self._bindEnv();
    },
    /*
     * 判斷傳進來的容器參數類型
     */
    _type: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        if(_config.container != '') {

            if($.isPlainObject(_config.container)) {
            _config.container = _config.container;

            }else if(/^\./.test(_config.container)){
                _config.container = $(_config.container);

            }else if(/^#/.test(_config.container)) {
                _config.container = $(_config.container);

            }else if($('#' + _config.container)) {
                _config.container = $('#' + _config.container);

            }else {
                alert('傳參的類型有誤!請重新傳參!');
            }

        }else {
            return;
        }
    },
    /*
     * 渲染html
     */
    _renderHTML: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var html = '';
        html += '<span class="'+_config.elCls+'-amount-wrap">' + 
                    '<input type="text" title="請輸入數字" value="'+_config.val+'" class="'+_config.elCls+'-amount-input"/>' +
                    '<span class="'+_config.elCls+'-amount-increase"></span>' + 
                    '<span class="'+_config.elCls+'-amount-decrease"></span>' + 
                '</span>';
        $(_config.container).append(html);
    },
    /*
     * 點擊事件
     */
    _bindEnv: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;

        // 點擊事件 事件代理
        $(_config.container).unbind('click');
        $(_config.container).bind('click',function(e){
            var target = e.target;
            if($(target).hasClass(_config.elCls+"-amount-increase")) {
                // 執行increase method
                self.increase();

            }else if($(target).hasClass(_config.elCls+"-amount-decrease")) {
                // 執行 decrease method
                self.decrease();
            }
        });
        
        // 鍵盤事件 鍵盤向上 鍵碼是38 向下是 40
        $('.' + _config.elCls+"-amount-input",_config.container).keyup(function(e){
            
            var keyCode = e.keyCode;
            if(keyCode == 40) {
                self.decrease();
            }else if(keyCode == 38) {
                self.increase();
            }
        });

    },
    /*
     * 增加方法 獲取input值 然后加個步長 (每次點擊時候 判斷此值是否大於maxVal)
     * @method {increase public}
     */
    increase: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;

        var inputVal = $.trim($('.' + _config.elCls + "-amount-input",_config.container).attr('value'));
        if(inputVal * 1 < _config.maxVal * 1) {
            
            var curVal = self._addFun(inputVal * 1,_config.step * 1);
            if(curVal >= _config.maxVal * 1) {
                curVal = _config.maxVal * 1;
            }
            $('.' + _config.elCls + "-amount-input",_config.container).val(curVal);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',curVal);

            // 回調
            _config.nextFunc && $.isFunction(_config.nextFunc) && _config.nextFunc({value:curVal});
        }
            
    },
    /*
     * 減少方法 獲取input值 然后減去步長 (每次點擊時候 判斷此值是否大於minVal)
     * @method {decrease public}
     */
    decrease: function() {
        var self = this,
            _config = self.config;
        var inputVal = $.trim($('.' + _config.elCls + "-amount-input",_config.container).attr('value'));
        if(inputVal * 1 > _config.minVal * 1) {
            var curVal = self._subtraction(inputVal * 1, _config.step * 1);
            if(curVal <= _config.minVal * 1) {
                curVal = _config.minVal * 1;
            }
            $('.' + _config.elCls + "-amount-input",_config.container).val(curVal);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',curVal);

            // 回調
            _config.prevFunc && $.isFunction(_config.prevFunc) && _config.prevFunc({value:curVal});
        }
    },
    /*
     * 可以供外部直接設置值
     * @method {setVal public} 
     */
    setVal: function(val) {
        var self = this,
            _config = self.config;

        // 簡單的判斷下 此值是否是數字型的
        if(/\d/.test(val)) {
            $('.' + _config.elCls + "-amount-input",_config.container).val(val);
            $('.' + _config.elCls + "-amount-input",_config.container).attr('value',val);
        }
    },
    /*
     * JS加法 解決精度問題
     * @method {_addFun private}
     * @param {arg1,arg2} int或者float,double
     */ 
    _addFun: function(arg1,arg2) {
         var firstArg,
             lastArg,
             differ,
             m;
        try{
            firstArg = arg1.toString().split('.')[1].length;
        }
        catch (e){
            firstArg = 0;
        }
        try{
            lastArg = arg2.toString().split('.')[1].length;
        }
        catch (e){
            lastArg = 0;
        }
        differ = Math.abs(firstArg - lastArg);
        m = Math.pow(10,Math.max(firstArg,lastArg));
        if(differ > 0) {
            var dm = Math.pow(10,differ);
            if(firstArg > lastArg) {
                arg1 = Number(arg1.toString().replace(".", ""));
                arg2 = Number(arg2.toString().replace(".", "")) * dm;

            }else {
                arg1 = Number(arg1.toString().replace(".", "")) * dm;
                arg2 = Number(arg2.toString().replace(".", ""));
            }
        }else {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", ""));
        }
        return (arg1 + arg2) / m;
    },
    /*
     * JS減法 解決精度問題
     * @method {_subtraction private}
     * @param {arg1,arg2} int或者float,double
     */
    _subtraction: function(arg1,arg2) {
        var firstArg,
         lastArg,
         differ,
         m;
         try{
            firstArg = arg1.toString().split('.')[1].length;
         }catch (e){
            firstArg = 0;
         }

         try{
            lastArg = arg2.toString().split('.')[1].length;
         }
         catch (e){
            lastArg = 0;
         }
         differ = Math.pow(10, Math.max(firstArg, lastArg));
         m = (firstArg > lastArg) ? firstArg : lastArg;
         return ((arg1 * differ - arg2 * differ) / differ).toFixed(m);
    }
 };
View Code

初始化代碼如下:

 // 初始化
     $(function(){
        var a = new Amount({
            container : '#demo1',
            step : '0.8',
            maxVal : '100'
        })
        $('#s40').click(function(){
            a.setVal(40);
        });
        $("#increase").click(function(){
            a.increase();
        });

        $("#decrease").click(function(){
            a.decrease();
        });
     });

 

demo下載


免責聲明!

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



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