关于表单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 类型。
解决思路
由于在 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 添加至翻墙白名单。你也可以通过导航栏上的社交网站与我联系