有一个快速的方法来设置HTML文本输入(<input type=text />),只允许数字击键(加上'.')?
当前回答
使用这个DOM:
<input type = "text" onkeydown = "validate(event)"/>
还有这个脚本:
validate = function(evt)
{
if ([8, 46, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, 36].indexOf(evt.keyCode || evt.which) == -1)
{
evt.returnValue = false;
if(evt.preventDefault){evt.preventDefault();}
}
}
...或者这个脚本,没有indexOf,使用两个for…
validate = function(evt)
{
var CharValidate = new Array("08", "046", "039", "948", "235");
var number_pressed = false;
for (i = 0; i < 5; i++)
{
for (Ncount = 0; Ncount < parseInt(CharValidate[i].substring(0, 1)) + 1; Ncount++)
{
if ((evt.keyCode || evt.which) == parseInt(CharValidate[i].substring(1, CharValidate[i].lenght)) + Ncount)
{
number_pressed = true;
}
}
}
if (number_pressed == false)
{
evt.returnValue = false;
if(evt.preventDefault){evt.preventDefault();}
}
}
我使用onkeydown属性而不是onkeypress,因为onkeydown属性是在onkeypress属性之前检查的。问题出在谷歌Chrome浏览器上。
与属性“onkeypress”,标签将不可控与“preventDefault”谷歌chrome,然而,与属性“onkeydown”,标签变成可控!
9 . TAB =>的ASCII码
第一个脚本的代码比第二个脚本少,但是ASCII字符数组必须包含所有的键。
第二个脚本比第一个脚本大得多,但是数组并不需要所有的键。数组每个位置的第一位数字是每个位置将被读取的次数。对于每一个读数,都将加1到下一个读数。例如: NCount = 0
48 + NCount = 48
NCount + +
48 + NCount = 49
NCount + +
...
48 + NCount = 57 在数字键只有10(0 - 9)的情况下,但如果它们是100万个,那么创建一个包含所有这些键的数组就没有意义了。
ASCII代码:
8 ==>(退格); 46 =>(删除); 37 =>(左箭头); 39 =>(右箭头); 48 - 57 =>(数字); 36 => (home); 35 => (end);
其他回答
这是一个改进的函数:
function validateNumber(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
if ((key < 48 || key > 57) && !(key == 8 || key == 9 || key == 13 || key == 37 || key == 39 || key == 46) ){
theEvent.returnValue = false;
if (theEvent.preventDefault) theEvent.preventDefault();
}
}
这里有一个简单的例子,它只允许有一个小数,不能再多了。输入事件使用regex替换基于以下两种模式的文本:
删除任何不是数字或点的东西 删除点的任何第二个实例
<input type="text" oninput="this. "Value = this.value.replace(/[^0-9。.replace) / g,”) (/(\..*?)\..* / g, 1美元);”/>
正如下面有人评论的那样,上面的解决方案不处理前导零。如果你的特定用例要求这些是不允许的,你可以像这样添加到上面的模式:
<input type="text" oninput="this. "Value = this.value.replace(/[^0-9。.replace) / g,”) (/(\..*?)\..* / g, 1美元).replace(/ ^ 0 ^。] /, ' 0 ');“/>
这将允许0.123或。123,但不允许0123或00.123。
我用完了这个函数:
onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) return false;"
这在IE和Chrome中工作得很好,我不知道为什么它在firefox中也不工作得很好,这个功能在firefox中阻止了tab键。
对于tab键在firefox中工作很好,添加这个:
onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) if(event.keyCode != 9) return false;"
jQuery的另一个简单方法:
$('.Numeric').bind('keydown',function(e){
if (e.which < 48 || e.which > 57)
return false;
return true;
})
现在只需将每个输入类设置为Numeric,如下所示:
<input type="text" id="inp2" name="inp2" class='Numeric' />
JavaScript
你可以用下面的setInputFilter函数过滤text <input>的输入值(支持复制+粘贴,拖放,键盘快捷键,上下文菜单操作,不可输入键,插入号位置,不同的键盘布局,有效性错误消息,以及ie9以来的所有浏览器):
// Restricts input for the given textbox to the given inputFilter function.
function setInputFilter(textbox, inputFilter, errMsg) {
[ "input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) {
textbox.addEventListener(event, function(e) {
if (inputFilter(this.value)) {
// Accepted value.
if ([ "keydown", "mousedown", "focusout" ].indexOf(e.type) >= 0){
this.classList.remove("input-error");
this.setCustomValidity("");
}
this.oldValue = this.value;
this.oldSelectionStart = this.selectionStart;
this.oldSelectionEnd = this.selectionEnd;
}
else if (this.hasOwnProperty("oldValue")) {
// Rejected value: restore the previous one.
this.classList.add("input-error");
this.setCustomValidity(errMsg);
this.reportValidity();
this.value = this.oldValue;
this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
}
else {
// Rejected value: nothing to restore.
this.value = "";
}
});
});
}
你现在可以使用setInputFilter函数来安装一个输入过滤器:
setInputFilter(document.getElementById("myTextBox"), function(value) {
return /^\d*\.?\d*$/.test(value); // Allow digits and '.' only, using a RegExp.
}, "Only digits and '.' are allowed");
对输入错误类应用您首选的样式。这里有一个建议:
.input-error{
outline: 1px solid red;
}
请注意,您仍然必须进行服务器端验证!
另一个警告是,这将破坏撤销堆栈,因为它设置了这个。直接价值。 这意味着CtrlZ不能在输入无效字符后撤销输入。
Demo
查看JSFiddle演示以获得更多输入过滤器示例或运行下面的堆栈代码片段:
// Restricts input for the given textbox to the given inputFilter. function setInputFilter(textbox, inputFilter, errMsg) { [ "input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) { textbox.addEventListener(event, function(e) { if (inputFilter(this.value)) { // Accepted value. if ([ "keydown", "mousedown", "focusout" ].indexOf(e.type) >= 0) { this.classList.remove("input-error"); this.setCustomValidity(""); } this.oldValue = this.value; this.oldSelectionStart = this.selectionStart; this.oldSelectionEnd = this.selectionEnd; } else if (this.hasOwnProperty("oldValue")) { // Rejected value: restore the previous one. this.classList.add("input-error"); this.setCustomValidity(errMsg); this.reportValidity(); this.value = this.oldValue; this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd); } else { // Rejected value: nothing to restore. this.value = ""; } }); }); } // Install input filters. setInputFilter(document.getElementById("intTextBox"), function(value) { return /^-?\d*$/.test(value); }, "Must be an integer"); setInputFilter(document.getElementById("uintTextBox"), function(value) { return /^\d*$/.test(value); }, "Must be an unsigned integer"); setInputFilter(document.getElementById("intLimitTextBox"), function(value) { return /^\d*$/.test(value) && (value === "" || parseInt(value) <= 500); }, "Must be between 0 and 500"); setInputFilter(document.getElementById("floatTextBox"), function(value) { return /^-?\d*[.,]?\d*$/.test(value); }, "Must be a floating (real) number"); setInputFilter(document.getElementById("currencyTextBox"), function(value) { return /^-?\d*[.,]?\d{0,2}$/.test(value); }, "Must be a currency value"); setInputFilter(document.getElementById("latinTextBox"), function(value) { return /^[a-z]*$/i.test(value); }, "Must use alphabetic latin characters"); setInputFilter(document.getElementById("hexTextBox"), function(value) { return /^[0-9a-f]*$/i.test(value); }, "Must use hexadecimal characters"); .input-error { outline: 1px solid red; } <h2>JavaScript input filter showcase</h2> <p>Supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, and <a href="https://caniuse.com/#feat=input-event" target="_blank">all browsers since IE 9</a>.</p> <p>There is also a <a href="https://jsfiddle.net/emkey08/tvx5e7q3" target="_blank">jQuery version</a> of this.</p> <table> <tr> <td>Integer</td> <td><input id="intTextBox"></td> </tr> <tr> <td>Integer >= 0</td> <td><input id="uintTextBox"></td> </tr> <tr> <td>Integer >= 0 and <= 500</td> <td><input id="intLimitTextBox"></td> </tr> <tr> <td>Float (use . or , as decimal separator)</td> <td><input id="floatTextBox"></td> </tr> <tr> <td>Currency (at most two decimal places)</td> <td><input id="currencyTextBox"></td> </tr> <tr> <td>A-Z only</td> <td><input id="latinTextBox"></td> </tr> <tr> <td>Hexadecimal</td> <td><input id="hexTextBox"></td> </tr> </table>
打印稿
下面是它的TypeScript版本。
function setInputFilter(textbox: Element, inputFilter: (value: string) => boolean, errMsg: string): void {
["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) {
textbox.addEventListener(event, function(this: (HTMLInputElement | HTMLTextAreaElement) & { oldValue: string; oldSelectionStart: number | null, oldSelectionEnd: number | null }) {
if (inputFilter(this.value)) {
this.oldValue = this.value;
this.oldSelectionStart = this.selectionStart;
this.oldSelectionEnd = this.selectionEnd;
}
else if (Object.prototype.hasOwnProperty.call(this, "oldValue")) {
this.value = this.oldValue;
if (this.oldSelectionStart !== null &&
this.oldSelectionEnd !== null) {
this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
}
}
else {
this.value = "";
}
});
});
}
jQuery
还有一个jQuery版本。请看这个答案。
HTML5
HTML5有一个原生的解决方案<input type="number">(参见规范和文档)。文档中有这个输入类型的工作演示。
Instead of reading the value property, read the valueAsNumber property of the input to get the typed value as a number rather than a string. Usage inside a <form> is recommended because validation is made easier this way; for example, pressing Enter will automatically show an error message if the value is invalid. You can use the checkValidity method or the requestSubmit method on the entire form in order to explicitly check the validity. Note that you might need to use the required attribute in order to disallow an empty input. You can use the checkValidity method or the validity property on the input element itself in order to explicitly check the validity. You can use reportValidity to show an error message and use setCustomValidity to set your own message.
这种方法从根本上具有不同的用户体验:允许输入无效字符,并且单独执行验证。 这样做的好处是撤销堆栈(CtrlZ)不会中断。 注意,无论您选择哪种方法,都必须执行服务器端验证。
但请注意,浏览器支持不同:
大多数浏览器只在提交表单时验证输入,而在输入时不验证。 大多数移动浏览器不支持step、min和max属性。 Chrome(版本71.0.3578.98)仍然允许用户在字段中输入字符e和e。另请参阅问答为什么HTML输入type="number"允许在字段中输入字母e ? Firefox(版本64.0)和Edge (EdgeHTML版本17.17134)仍然允许用户在字段中输入任何文本。
Demo
document.querySelector("form").addEventListener("submit", (event) => { event.preventDefault(); console.log(`Submit! Number is ${event.target.elements.number.valueAsNumber}, integer is ${event.target.elements.integer.valueAsNumber}, form data is ${JSON.stringify(Object.fromEntries(new FormData(event.target).entries()))}.`); }) label { display: block; } <form> <fieldset> <legend>Get a feel for the UX here:</legend> <label>Enter any number: <input name="number" type="number" step="any" required></label> <label>Enter any integer: <input name="integer" type="number" step="1" required></label> <label>Submit: <input name="submitter" type="submit"></label> </fieldset> </form>
推荐文章
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- 向HTML表中添加水平滚动条
- jQuery: keyPress退格键不火?
- XMLHttpRequest Origin null不允许Access-Control-Allow-Origin for file:/// to file:///(无服务器)
- 在notepad++中格式化代码
- 表单中包含表单,可以吗?
- 如何创建表只使用<div>标签和Css
- html5 - canvas元素-多层
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?