zoukankan      html  css  js  c++  java
  • 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;
            /*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下载

  • 相关阅读:
    242
    241
    240
    「音乐」(G)I-DLE—화(火花) (HWAA)
    「音乐」Red Velvet—Psycho
    「音乐」Taylor Swift—the lakes (bonus track)
    「笔记」DP简单笔记
    「游记」CSP2020-S2游记
    「音乐」BLACKPINK-Ice Cream (with Selena Gomez)
    matlab 2021a linux 版本下载
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/3512363.html
Copyright © 2011-2022 走看看