目录
  1. 1. 问题描述
    1. 1.1. 需求是这样的
    2. 1.2. 最初思路
  2. 2. 相关知识
  3. 3. 解决思路

关于表单input type="number"非法值时的一些探究及拓展

问题描述

需求是这样的

今天在处理表单验证时发现了一个很诡异的现象,遂记录下来。

事情是这样的: 产品 MM 提了个需求,在微信端要求做一个表单,提交一些信息,然后其中有一个 input 需要直接调用数字键盘

最初思路

既然调用数字键盘,那么 input type 肯定就是 number 或者 tel。因为 tel 不能输入小数点,所以input type就为 number 了,然后在填表单时要做一些验证来及时反馈吧,所以代码大概就是这样的了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<input type="number" name="retail_price" id="retail_price" placeholder="">

alertDebug:function(formbug){
       let alertcontent ={
         6:'整数位最多不超过4位,小数位最多不超过2位',
       }
       let texts = {}
       texts.text = alertcontent[formbug]
       this.$dispatch('alertMsg',texts);
     },
     submitForm: function(event){
       let eventname = '';
       let formbug = false;
       if(this.$data.retail_price != ''){
         if(!this.validateNum(this.$data.retail_price) || this.checklength(this.$data.retail_price) > 4){
           if(!this.validateNum(this.$data.retail_price)){
             if(!eventname){
               formbug = 6;
             }
             if(eventname == 'retail_price'){
               formbug = 6;
               let temp = this.retail_price;
               this.retail_price = temp.toString().slice(0,-1);
               event.target.value = temp.toString().slice(0,-1);
             }
           }else{
             let retailprice = this.$data.retail_price + '';
             if(retailprice.indexOf('.') > -1){
               if(this.checklength(this.$data.retail_price) > 7){
                 if(!eventname){
                   formbug = 6;
                 }
                 if(eventname == 'retail_price'){
                   formbug = 6;
                   let temp = this.retail_price;
                   this.retail_price = temp.toString().slice(0,-1);
                   event.target.value = temp.toString().slice(0,-1);
                 }
               }
             }else{
               if(!eventname){
                 formbug = 6;
               }
               if(eventname == 'retail_price'){
                 formbug = 6;
                 let temp = this.retail_price;
                 this.retail_price = temp.toString().slice(0,-1);
                 event.target.value = temp.toString().slice(0,-1);
               }
             }
           }
         }
       }
       if(formbug){
         this.alertDebug(formbug);
         return false;
       }
     },

这样出现了一个问题在电脑 Chrome,iphone上,对于 input type="number" 的 input 都会将 value 变为 "";而在安卓的微信上却显示为正确的 input number 格式(如输入值为 "1...." 时,由于值并不为数字,非法,大多数按照[W3C相关规范]( http://www.w3.org/TR/html5/forms.html#number-state-(type=number))会将它处理为 "",而在 Android 微信上为 "1.")

相关知识

这里主要就是 input 的 number;其为 html5 加入的 type 类型。

input html5 添加内容介绍

解决思路

由于在 W3C 规范中,如果输入了一些非数字的字符,就会返回空字符串。

但这样其实比较坑,导致验证的时候如果输入非数字的时候,直接使用 .value( 或者$('.selector').val())都拿不到值,而拿不到值的情况下就会认为没有填写这个输入框。

这里的解决方案就是在 input 的属性中有一个 validity 属性:

在 Chrome 中,input 元素的 validity.badInput 这个属性里,可以判断值是否合法,如果填入了非法值,这个属性就是 true,正常值的话就是 false。

但是火狐下 .validity 里没有 badInput 属性,如下图,它可以直接通过.value 正常返回非数字的字符串。(微信 X5 同样也这样..) 安卓微信

而 IE8、9 则也可以直接 .value 获取到非数字的字符串值,不会返回空字符串。

本文版权归 yangzj1992 所有。来源青春样博客(qcyoung.com),商业转载请联系本人获得授权,非商业转载请注明出处。


本博客采用 Disqus 作为评论解决方案,目前 Disqus 经常被 GFW 封锁,若想参与评论请翻墙访问本站或将 disqus.com 添加至翻墙白名单。你也可以通过导航栏上的社交网站与我联系