动手写个数字输入框1:input[type=number]的遗憾

简介:

前言

 最近在用Polymer封装纯数字的输入框,开发过程中发现不少坑,也有很多值得研究的地方。本系列打算分4篇来叙述这段可歌可泣的踩坑经历:

  1. 《动手写个数字输入框1:input[type=number]的遗憾》
  2. 《动手写个数字输入框2:起手式——拦截非法字符》
  3. 《动手写个数字输入框3:痛点——输入法是个魔鬼》
  4. 《动手写个数字输入框4:魔鬼在细节——打磨光标位置》

HTML5带来的福利-input[type=number]

347002-20170529170708039-1526182133.png

<input
    id="age" name="age"
    type="number" step="1" min="0" max="120">
<input
    id="inc"
    type="button" value="增加">
<input
    id="dec"
    type="button" value="减少">

<script>
    /* 工具函数...无视我吧:D */
    const comp =
           (...fns) =>
           (...args) => {
             let len = fns.length
             while (len--){
               args = [fns[len].apply(null, args)]
             }
             return args.length > 1 ? args : args[0]
           }
    const isSome = x => 'undefined' !== typeof x && x !== null
    const invokerImpl =
            n =>
        o =>
            m =>
            (...args) => {
              let args4m = args.splice(0, n)
                , times = parseInt(args[0]) || 1
                , ret = []
              while (times--){
                ret.push(o[m].apply(o, args4m))
              }
              return ret.length > 1 ? ret : ret[0]
            }
    const curry2Partial =
        fn =>
        (...args) => {
            let c = true
                , i = 0
                , l = args.length
                , f = fn
            for (;c && i < l; ++i){
                c = isSome(args[i])
                if (c){
                    f = f(args[i])
                }
            }
            return f
        }
    const invoker = curry2Partial(invokerImpl)
    const invoker0 = invoker(0)
    const $ = invoker(1, document, "querySelectorAll")
    const invoker0AtEl = comp(invoker0, $)

    /* 继续无视我吧:D */
    const invoker0AtAge = invoker0AtEl('#age')

    // input[type=number]提供stepUp和stepDown两个方法来增加和减少数字
    const incAge = invoker0AtAge('stepUp')
            , decAge = invoker0AtAge('stepDown')
    $('#inc').addEventListener('click', incAge)
    $('#dec').addEventListener('click', decAge)
</script>

input[type=number]为我们提供了如下特性:

  1. 限制只能输入[+-0-9.]这几个字符
  2. 输入法(IME)也无法输入非[+-0-9.]的字符
  3. 自动的表单验证
  4. minmax来限制数值的下限和上限;
  5. 提供stepUp和stepDown两个方法实现以编程方式控制数值的增加和减少;
  6. 移动设备上当它获得焦点时,会出现数字键盘;
  7. step设置点击右侧微调按钮的步长(默认为1),可设置为小数、整数或anystep的值除了影响微调按钮的步长外,还影响表单验证信息。
<!-- step为整数时 -->
<input name="age1" type="number"
    step="1" value="1">
<input name="age1" type="number"
    step="1" value="1.1">

<!-- step为小数时 -->
<input name="age2" type="number"
    step="0.1" value="1">
<input name="age2" type="number"
    step="0.1" value="1.1">
<input name="age2" type="number"
    step="0.1" value="1.11">

<!-- step为any时 -->
<input name="age3" type="number"
    step="any" value="1">
<input name="age3" type="number"
    step="any" value="1.1">
<input name="age3" type="number"
    step="any" value="1.11">

<script>
  // 显示 true false
    $('[name=age1]').forEach(el => console.log(el.validity.valid))
  // 显示 true true false
    $('[name=age2]').forEach(el => console.log(el.validity.valid))
  // 显示 true true true
    $('[name=age3]').forEach(el => console.log(el.validity.valid))
</script>

另外,设置为any是让表单验证不受精度限制而已,实际上步长依然为1。

遗憾了我的哥

 到这里我想大家都会发现怎么少了个精度设置呢?确实,input[type=number]并没有为我们提供设置精度的属性或方法。但遗憾的何止是这个呢?

  1. 木有精度精度设置;
  2. 不想要右侧的微调按钮还不行了...
  3. 点击微调按钮和调用stepUpstepDown设置数值确实被限制在minmax区间,但直接输入却不受限制...
  4. 可以输入多个小数点,如2012.12.12;
  5. 设置step=any后,chrome on android的数字键盘居然没了小数点按键。
  6. 设置step=any后,点击微调按钮步长为1,但调用stepUpstepDown则报

    Uncaught DOMException: Failed to execute 'stepUp' on 'HTMLInputElement': This form element does not have an allowed value step.

隐藏右侧微调按钮不完全解决方法

Webkit和Gecko下可通过以下的CSS来隐藏右侧微调按钮

/* chrome */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{
    -webkit-appearance: none!important;
    margin: 0;
}
/* Firefox */
input[type=number]{
    -moz-appearance: textfield;
}

IE就没辙了:-(

总结

 也许你会问既然HTML5愿意为我们新增一个全新的input[type=number],为什么偏偏提供一个缺胳膊少腿的呢?只能说得哥情时失嫂意,既然它不满足,那就自己写写看咯:)
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/6918305.html ^_^肥仔John

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!

posted @ 2017-05-31 09:01 ^_^肥仔John 阅读( 3530) 评论( 3) 编辑 收藏
  
#1楼 2017-05-31 09:21 笑对当空  
难道楼主完美解决了number?
厉害了....
  
#2楼 2017-05-31 09:22 幻天芒  
期待后续~
http://pic.cnblogs.com/face/343299/20150320135757.png
  
#3楼 3703844 2017/5/31 11:14:02 2017-05-31 11:14 逗伴不是瓣  
這才叫6。真的es6
http://pic.cnblogs.com/face/841362/20161108131728.png

公告

本文转自^_^肥仔John博客园博客,原文链接:http://www.cnblogs.com/fsjohnhuang/p/6918305.html/,如需转载请自行联系原作者

 

 

相关文章
|
4月前
|
前端开发
input去掉输入框type为number时的上下箭头的实现方法
input去掉输入框type为number时的上下箭头的实现方法
39 0
|
JavaScript
VUE element-ui之输入框限制只能输入数字number类型及表单校验
VUE element-ui之输入框限制只能输入数字number类型及表单校验
2160 0
VUE element-ui之输入框限制只能输入数字number类型及表单校验
|
前端开发
css:input数字编辑框number去掉右侧上下箭头
css:input数字编辑框number去掉右侧上下箭头
267 0
css:input数字编辑框number去掉右侧上下箭头
|
移动开发 前端开发
火狐谷歌浏览器去掉input type=number时控件的方法
火狐谷歌浏览器去掉input type=number时控件的方法
|
5月前
|
算法
Leetcode 313. Super Ugly Number
题目翻译成中文是『超级丑数』,啥叫丑数?丑数就是素因子只有2,3,5的数,7 14 21不是丑数,因为他们都有7这个素数。 这里的超级丑数只是对丑数的一个扩展,超级丑数的素因子不再仅限于2 3 5,而是由题目给定一个素数数组。与朴素丑数算法相比,只是将素因子变了而已,解法还是和朴素丑数一致的。
63 1
|
5月前
|
存储
Leetcode Single Number II (面试题推荐)
给你一个整数数组,每个元素出现了三次,但只有一个元素出现了一次,让你找出这个数,要求线性的时间复杂度,不使用额外空间。
21 0
LeetCode 136. 只出现一次的数字 Single Number
LeetCode 136. 只出现一次的数字 Single Number
LeetCode contest 177 5169. 日期之间隔几天 Number of Days Between Two Dates
LeetCode contest 177 5169. 日期之间隔几天 Number of Days Between Two Dates
|
算法
LeetCode 414. Third Maximum Number
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
66 0
LeetCode 414. Third Maximum Number