如果有空格或非数字字符,HTML5 输入类型 = 数字值在 Webkit 中为空?
Posted
技术标签:
【中文标题】如果有空格或非数字字符,HTML5 输入类型 = 数字值在 Webkit 中为空?【英文标题】:HTML5 input type=number value is empty in Webkit if has spaces or non-numeric characters? 【发布时间】:2013-09-11 16:59:15 【问题描述】:这对我来说是一种奇怪的行为,但在 Webkit 浏览器(Chrome/Safari,not Firefox)上,如果我在 <input type=number>
的一串数字中包含一个空格,那么 value
输入为空。
查看这个 JSFiddle:http://jsfiddle.net/timrpeterson/CZZEX/5/
代码如下:
<input id='withOutspace' type='number' value='123'>
<input id='with_space' type='number' value='123 123'>
<button>click</button>
$('button').click(function()
alert("withOut:"+$('#withOutspace').val()+" |||| with:"+$('#with_space').val());
);
如果您转到this JSFiddle,您会注意到with_space
输入为空。但是如果你在其中输入一个带有空格或任何非数字字符的数字,警报会说输入为空。
显然,这对于使用信用卡号等进行表单验证来说是一场灾难。所以有人对此有破解吗?
【问题讨论】:
【参考方案1】:黑客是使用type="tel"
而不是type="number"
。
这解决了两个主要问题:
-
它在移动设备上拉出一个数字键盘
它使用数字或非数字作为输入验证(并且非为空)。
请看这个 JSFiddle:http://jsfiddle.net/timrpeterson/CZZEX/6/
【讨论】:
使用 tel 的问题是它显示的电话号码键盘没有小数或数字字段(例如货币)中经常使用的负号。 (在 iPhone 上测试) 是的,使用type="tel"
代替 type="number"
取决于用例。由于我上面提到的两个原因,信用卡(显然还有电话号码)使用type="tel"
会更好。
可访问性怎么样?这对屏幕阅读器来说不是很麻烦吗?【参考方案2】:
我可以提出两种方法。 1. 防止输入中的字符
# updated to support more numerical characters related
$(window).keydown(function(e)
if($('input[type=number]').index($(e.target))!=-1)
if(
($.inArray(e.keyCode, [48,49,50,51,52,53,54,55,56,57,58,96,97,98,99,100,101,102,103,104,105,8,13,190,189]) == -1) // digits, digits in num pad, 'back', 'enter', '.', '-'
|| (e.keyCode == 190 && $(e.target).val().indexOf(".") != -1) // not allow double dot '.'
|| (e.keyCode == 190 && $(e.target).val().length == 0) // not allow dot '.' at the begining
)
e.preventDefault();
);
或 2. 即时更改输入的类型
$('input[type=number]').focus(function()
$(this).prop('type', 'text');
);
这允许放任何你想要的东西并将它的类型改回onblur
$(this).blur(function()
$(this).prop('type', 'number');
);
但仍然您不能将非数字值存储在 type=number 的输入中,因此val()
在遇到字符或空格时将始终返回空字符串。
所以,至少你必须用.replace(/[^\d]/g, '')
删除所有垃圾 - 这意味着在你改回类型之前“删除除数字之外的所有垃圾”
在my example 中,我显示了这两种方法 + 清除输入值。
【讨论】:
我也会将代码 97-106(小键盘数字)添加到允许列表中。 这里描述的事件墙是我目前发现的最好的解决方法 我包括所有这些 keyCodes48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 8, 13, 190, 189
。分别是:数字、数字键盘中的数字、'back'、'enter'、'.'、'-'
我们还必须注意像“10..34”这样的双点,这会使数字字段再次失败。我正在用所有这些建议编辑原始答案
在 Chrome 41 上,如果您将输入类型从数字更改为文本,它会清除阻止您执行“快速转换”的值【参考方案3】:
控制输入数字的一种方法是在无法读取值时将其设置为空
static formattedDecimalInput(input, maxScale, allowEmpty = true)
input = $(input);
input.on("blur", function(e)
var inputVal = input.val();
if(inputVal != "" || !allowEmpty)
if(inputVal == "")
inputVal = "0";
var number = Number(inputVal);
input.val(number.toFixed(maxScale));
else
input.val("");
);
你可以顺便格式化一下,如果你在服务器端有无效的字符,你可以发送一个错误的请求响应。
如果您想要一个必填字段,您可以在服务器调用之前使用 javascript 检查输入是否为空
这并不是最初问题的真正答案,但是当我到达这里时,我正在寻找一种用户友好的控件来处理这种类型的输入
【讨论】:
【参考方案4】:您正在将数字输入字段设置为不是数字的字符串。你期望会发生什么?重点是这些字段不允许或接受非数字输入。它们是 documented,因为只接受 floating point 值。
没有可用或需要的“hack”;解决方案是停止将number
输入字段用于不是数字的值。信用卡、电话号码等;这些东西不是数字。它们包含数字作为有效字符的子集,但它们也包含完全非数字的字符,如空格、连字符和括号。它们需要作为常规字符串存储和处理。
使用<input type="text"/>
。
【讨论】:
如果我这么疯狂,为什么 Firefox 将其保存为字符串?这似乎是最具包容性/最安全的默认行为。此外,type=number
更适合移动设备,因为它会拉起数字键盘。我必须恭敬地不同意这一点。
您可以将输入字段的 inputmode (html5) 属性设置为“数字”。这可能会给你数字键盘
What did you expect to happen?
valueAsNumber
返回NaN
,这是有道理的。 value
返回一个空字符串,这不允许我对约束添加放松,例如删除空格、规范使用 .
或 ,
作为小数分隔符...
What did you expect to happen?
- 我希望如果我在此字段中输入文本而不是数字 - 如果允许 - 在表单提交时,文本不会被清除,我看到我输入了错误的东西。目前,我的允许空值的数字字段在清除数字字段中的字母字符后自动成功提交。这是不正确的行为(至少在 Firefox 中可见)。
您预计会发生什么?好吧,我希望能够检测出空字段和垃圾字段之间的区别,这样我就可以告诉用户要修复什么。当它有非数字数据时告诉用户“数字字段不能为空”让我看起来很愚蠢。我想告诉他们“请在数字字段中只输入数字数据。”【参考方案5】:
我对这个问题的破解包括以下内容(我使用 jQuery 验证器):
$(document).on('keyup', '[type="number"]', function ()
if (this.validity.badInput)
$(this).attr('data-badinput', true);
);
稍后在验证器方法中我会这样做:
$.validator.addMethod('isInteger', function (value, element, parameterValue)
if ($(element).attr('data-badinput'))
//We know nasty browser always clears incorrect input, so empty string will look OK next time
$(element).removeAttr('data-badinput');
return false;
return !value || /^-?\d+$/.test(value);
);
【讨论】:
以上是关于如果有空格或非数字字符,HTML5 输入类型 = 数字值在 Webkit 中为空?的主要内容,如果未能解决你的问题,请参考以下文章