Как разрешить ввод только цифр в поле ввода [type = "number" ]?

У меня есть поле ввода, в котором пользователь должен иметь возможность вводить цифры [0-9].

document.getElementById("integer").addEventListener('input', restrictToInteger);
function restrictToInteger() {
    this.value = this.value.replace(/[^\d]/g, '');
}
<input type="number" id="integer" />

Ответ 1

Я думаю, причина в том, что браузер очищает входное значение, потому что строка с двумя точками не является числом.

Некоторые исправления о вашем коде:

Вам нужно изменить регулярное выражение, если вы хотите принять число с десятичной частью. Теперь вы только говорите, что хотите принимать цифры [0-9] и больше символов.

Для достижения желаемого вам нужно изменить /[^\d]/g на /[^\d.]/g.

document.getElementById("integer").addEventListener('input', restrictToInteger);

function restrictToInteger()
{
  this.value = this.value.replace(/[^\d.]/g, '');
}
<input type="number" id="integer" />

Ответ 2

На основе ответов Alexandru-Ionut Mihai и natchiketa я создал следующее решение:

document.getElementById("integer").addEventListener("input", allowOnlyDigits);

function allowOnlyDigits() {  
  if (this.validity.valid) {
    this.setAttribute('current-value', this.value.replace(/[^\d]/g, ""));
  }
  this.value = this.getAttribute('current-value');
}
<input type="number" id="integer" />

Ответ 3

Единственной проблемой был ваш тип ввода. Измените его на text, и он должен работать!

function validate(e) {
    var charCode = e.keyCode? e.keyCode : e.charCode
    if (!(charCode >= 48 && charCode <= 57)) {
        if(!(charCode>=37 && charCode<=40))
            if(charCode!=8 && charCode!=46)
            return false;
    }
}
<input type="number" id="integer" pattern="[0-9]"
onkeydown="return validate(event)"/>

Ответ 4

Вы можете достичь своего требования с помощью copying значения старого ввода и используя методы setAttribute и getAttribute для хранения значений.

function myFunction(input){
  input.setAttribute('current-value',"");
  input.oninput=function(){  
      let currentValue=input.getAttribute('current-value');
      if(input.value!='' || (currentValue>=1 && currentValue<=9))
        input.setAttribute('current-value',input.value);
      input.value=input.getAttribute('current-value');
  }
}
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>

Ответ 5

Я бы переключился на событие cancelable, например keydown.
Таким образом вы можете не набирать персонажа в первую очередь:

var cancelEvent = function (e) {
    e.preventDefault();
    return false;
},
restrictToInteger = function restrictToInteger(e) {
    var acceptableInput = /[0-9]/g,
        clipboardKeys = /[zxcv]/ig,
        field = e.key || e.char,
      isClipboardOperation = (clipboardKeys.test(field) && e.ctrlKey),
        inputIsAcceptable = field ? (
            acceptableInput.test(field)
            || field.length > 1
            || isClipboardOperation
        ) : true;

    if (!inputIsAcceptable) {
        cancelEvent(e);
    }
},
ensureIntegerValueOnPaste = function ensureIntegerValueOnPaste(e) {
	var data = e.clipboardData || e.dataTransfer,
  		text = data.getData('text'),
        int = parseInt(this.value + text, 10);

    if (isNaN(int)) {
        cancelEvent(e);
    } else {
        window.setTimeout(function () {
            e.target.value = int;
        }, 0);
    }
},
input = document.getElementById("integer");

input.addEventListener('keydown', restrictToInteger);
input.addEventListener('drop', ensureIntegerValueOnPaste);
input.addEventListener('paste', ensureIntegerValueOnPaste);
<input type="number" id="integer" />

Ответ 6

Когда вы вызываете oninput, элемент <input> сначала вызывает свои внутренние методы для обработки значения. Это не позволяет вашей функции видеть какие-либо действительные ошибочные символы, а именно e+-. - все используемые JavaScript для форматирования чисел.

Это можно увидеть, добавив console.log вызовы до и после изменения this.value.

console.log(this.value);
this.value=this.value.replace(/[^\d]/g, '');
console.log(this.value);

Нет никакой разницы!

Если вы попытаетесь, например:

console.log(this.value);
this.value+=1; // or *=2 for numerical fun
console.log(this.value);

вы можете видеть разницу.

Таким образом, ваша функция ускоряет обычные внутренние вызовы <input type='number'/>, как правило, при обработке незаконного ввода.

Не могу понять, почему поле осталось пустым, а не 1.

Ответ 7

HTML 4 имеет событие под названием onkeypress. С этим атрибутом мы можем сделать это без использования дополнительного JS:

<input type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0 || event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 57">

Ответ 8

Вам не нужно регулярное выражение, вы можете использовать функцию parseFloat(). Тип ввода остается неизменным, есть все еще "стрелки" для увеличения/уменьшения номера, а также он гарантирует, что ваш вход не начнется с нуля.

document.getElementById("integer").addEventListener('input', restrictToInteger);
function restrictToInteger() {
  this.value = parseFloat(this.value);
}
<input type="number" id="integer" />

Ответ 9

Вы должны проверить, не является ли это число, а затем остановить пользователя.

document.getElementById("integer").addEventListener('input', restrictToInteger);

function restrictToInteger(e)
{
  if(isNaN(e.data)){
     alert("only numbers allowed");
  }
}
<input type="number" id="integer" />