HTML文本输入只允许输入数字
使用这个DOM
和这个脚本
function validate(evt) { var theEvent = evt || window.event; // Handle paste if (theEvent.type === 'paste') { key = event.clipboardData.getData('text/plain'); } else { // Handle key press var key = theEvent.keyCode || theEvent.which; key = String.fromCharCode(key); } var regex = /[0-9]|\./; if( !regex.test(key) ) { theEvent.returnValue = false; if(theEvent.preventDefault) theEvent.preventDefault(); } }
JavaScript
使用以下setInputFilter
函数可以过滤文本的输入值(支持复制 + 粘贴、拖放、键盘快捷键、上下文菜单操作、不可打的键、插入符位置、不同的键盘布局、有效性错误信息和自IE 9以来的所有浏览器):
// 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
类。以下是一个建议:
.input-error{ outline: 1px solid red; }
请注意,您仍然必须进行服务器端验证!
另一个注意事项是,这会破坏撤销堆栈,因为它会直接设置this.value
。这意味着在键入无效字符后, Ctrl Z 将无法撤消输入。
Demo
请查看JSFiddle演示以获取更多输入过滤器示例,或运行下面的Stack片段:
// 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; }
JavaScript input filter showcase
Supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, and all browsers since IE 9.
There is also a jQuery version of this.
Integer | |
Integer >= 0 | |
Integer >= 0 and <= 500 | |
Float (use . or , as decimal separator) | |
Currency (at most two decimal places) | |
A-Z only | |
Hexadecimal |
TypeScript
这是一个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具有在中本地解决方案(请参见规范和文档)。文档中演示了此输入类型的工作示例。
- 不要读取
value
属性,而是读取输入框的valueAsNumber
属性,以数值的形式获取输入的值,而不是字符串。 - 建议在
内使用,因为这样更容易进行验证;例如,如果输入的值无效,按下Enter会自动显示错误消息。
- 可以使用
checkValidity
方法或requestSubmit
方法在整个表单上显式检查验证。 - 请注意,您可能需要使用
required
属性来禁止空输入。
- 可以使用
- 您可以在输入元素本身上使用
checkValidity
方法或validity
属性来显示验证结果。 - 您可以使用
reportValidity
来显示错误消息,并使用setCustomValidity
设置自己的消息。
这种方法 fundamentally 具有不同的用户体验:您可以输入无效字符,而验证是分开进行的。
这样做的好处是撤销操作栈 (CtrlZ) 不会受到破坏。
请注意,无论您选择哪种方法,都必须执行服务器端验证。
然而要注意,浏览器的支持程度是不同的:
- 大多数浏览器只会在提交表单时验证输入,而不是在输入时验证。
- 大多数移动浏览器不支持
step
、min
和max
属性。 - Chrome(版本71.0.3578.98)仍允许用户在字段中输入字符
e
和E
。请参见问答为什么HTML输入框中使用type="number"
可以输入字母e
?。 - Firefox(版本64.0)和Edge(EdgeHTML版本17.17134)仍允许用户在字段中输入任何文本。
演示
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; }