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

前言

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

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

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

<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

时间: 2024-08-01 23:44:36

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

动手写个数字输入框2:起手式——拦截非法字符

前言  最近在用Polymer封装纯数字的输入框,开发过程中发现不是坑,也有不少值得研究的地方.本系列打算分4篇来叙述这段可歌可泣的踩坑经历: 1. <动手写个数字输入框1:input[type=number]的遗憾> 2. <动手写个数字输入框2:起手式--拦截非法字符> 3. <动手写个数字输入框3:痛点--输入法是个魔鬼> 4. <动手写个数字输入框4:魔鬼在细节--打磨光标位置> 从源头抓起--拦截非法字符  从<动手写个数字输入框1:inpu

js数字输入框(包括最大值最小值限制和四舍五入)_javascript技巧

由于原文已经介绍的很好了,现在只是一些翻译和小小的补充. 例子 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <

《自己动手写Docker》书摘之五: 增加容器资源限制

增加容器资源限制 上一节中,我们已经可以通过命令行mydocker run -ti的方式创建并启动容器,这一节我们将通过Cgroup对容器的资源进行控制. 这一节中我们将实现通过mydocker run -ti -m 100m -cpuset 1 -cpushare 512 /bin/sh的方式控制容器容器的内存和CPU配置. 定义Cgroups的数据结构 上一章中我们介绍了Cgroups包含的三个概念:  cgroup hierarchy中的节点,用于管理进程和subsystem的控制的关系.

WPF和Expression Blend开发实例:一个样式实现的数字输入框

原文:WPF和Expression Blend开发实例:一个样式实现的数字输入框 今天来一个比较奇淫技巧的手法,很少人用,同时也不推荐太过频繁的使用. 先上样式: <Style x:Key="NumberTextBox" TargetType="{x:Type FrameworkElement}"> <EventSetter Event="PreviewTextInput" Handler="TextBox_TextI

CSS按钮样式之button标签与input type=button的区别详解

转载文章,原文地址:http://ipmtea.net/css/201006/16_5.html   对于每个程序设计者来说,为用户提供一个风格统一的界面是一项不变的要求.但是在网页上实现这种风格统一却显得格外困难,因为不同操作系统.不同浏览器对网页内容的表现方式存在着差       对于每个程序设计者来说,为用户提供一个风格统一的界面是一项不变的要求.但是在网页上实现这种风格统一却显得格外困难,因为不同操作系统.不同浏览器对网页内容的表现方式存在着差异,而且这种差异几乎毫无规律性.在处理表单元

自己动手写一个java版简单云相册_java

动手写一个java版简单云相册,实现的功能是: 用户可以一次上传一个至多个文件. 用户可以下载其他人上传的图片. 用户可以查看其他所有人的图片. 用户只能删除通过自己IP上传的图片. 用到的技术: 文件上传下载.设计模式.Dom4j.xPath等. 先看下2个页面: 源代码: web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns=

关于动态控制 input type="image"对象

动态|对象|控制     前一阵在写Web控件的时候,写了一个继承ImageButton的控件,在Page_Load以后,发现在Client端显示的是<input type=image id...>,我用javascript在前端做控制,从 document.elements里面就是找不到这些imageButton对象,在MSDN里面查找,也是说 document.elements里面的对象,不包含type=image的Input对象.        后来,发现可以用以下方法解决!      

form 表单中的input type=text 是不是一定会被加在请求中

问题描述 现在有这么一个想法 ,是通过一个checkbox来控制 同一排的 input type=text 是否加到请求中, 由于是checkbox只有在选中的时候才会被加到请求中,而input 如何不让它加到请求中了,这样方便后面数据的处理. 解决方案 看你是要同步还是异步操作了如果是异步操作,使用ajaxfunction ajax_post(){ $.post("action",{param:paramValue}, //自己拼接参数,如果有就加上 function(data){

《自己动手写Docker》书摘之二: Linux Cgroups

Linux Cgroups介绍 上面是构建Linux容器的namespace技术,它帮进程隔离出自己单独的空间,但Docker又是怎么限制每个空间的大小,保证他们不会互相争抢呢?那么就要用到Linux的Cgroups技术. 概念 Linux Cgroups(Control Groups) 提供了对一组进程及将来的子进程的资源的限制,控制和统计的能力,这些资源包括CPU,内存,存储,网络等.通过Cgroups,可以方便的限制某个进程的资源占用,并且可以实时的监控进程的监控和统计信息.  Cgrou