Voorkom dat u niet-numeriek typt in het invoertypenummer

Het gebruik van <input type=number>zorgt ervoor dat this.valuebinnen een gebeurtenislistener een lege tekenreeks retourneert als de invoer geen geldig nummer is. U kunt een voorbeeld hiervan zien op http://jsfiddle.net/fSy53/

De ongeldige tekens worden echter nog steeds weergegeven in de invoer.

Is er een manier om de waarde die daadwerkelijk wordt weergegeven, inclusief de ongeldige tekens, vanuit een gebeurtenislistener te krijgen?

Mijn uiteindelijke doel is om te voorkomen dat gebruikers niet-numerieke tekens in het veld typen. Ik moet type=numbergebruiken zodat het numerieke virtuele toetsenbord door mobiele apparaten wordt gebruikt. Mijn doel zou zijn om iets te doen als this.value = this.value.replace(/[^0-9.]/g, "")op keyup keypress, maar dit werkt niet, want als een ongeldig teken wordt getypt, levert het lezen van this.value""op.


Antwoord 1, autoriteit 100%

Probeer het standaardgedrag te voorkomen als de waarde van de binnenkomende sleutel niet bevalt:

document.querySelector("input").addEventListener("keypress", function (evt) {
    if (evt.which < 48 || evt.which > 57)
    {
        evt.preventDefault();
    }
});

Antwoord 2, autoriteit 26%

U kunt dit bereiken door te voorkomen dat de keyPress-gebeurtenis optreedt voor niet-numerieke waarden

bijv. (met jQuery)

$('.input-selector').on('keypress', function(e){
  return e.metaKey || // cmd/ctrl
    e.which <= 0 || // arrow keys
    e.which == 8 || // delete key
    /[0-9]/.test(String.fromCharCode(e.which)); // numbers
})

Dit houdt rekening met alle verschillende soorten invoer (bijv. invoer vanaf het numerieke toetsenblok heeft andere codes dan het toetsenbord) evenals backspace, pijltjestoetsen, control/cmd + r om opnieuw te laden, enz.


Antwoord 3, autoriteit 19%

Houd er rekening mee dat e.which, e.keyCodeen e.charCodezijn verouderd: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which

Ik geef de voorkeur aan e.key:

document.querySelector("input").addEventListener("keypress", function (e) {
    var allowedChars = '0123456789.';
    function contains(stringValue, charValue) {
        return stringValue.indexOf(charValue) > -1;
    }
    var invalidKey = e.key.length === 1 && !contains(allowedChars, e.key)
            || e.key === '.' && contains(e.target.value, '.');
    invalidKey && e.preventDefault();});

Deze functie interfereert niet met controlecodes in Firefox (Backspace, Tab, enz.) door de stringlengte te controleren: e.key.length === 1.

Het voorkomt ook dubbele punten aan het begin en tussen de cijfers: e.key === '.' && contains(e.target.value, '.')

Helaas voorkomt het niet dat er meerdere punten aan het einde komen: 234....

Het lijkt erop dat er geen manier is om ermee om te gaan.


Antwoord 4, autoriteit 7%

De andere antwoorden leken ingewikkelder dan nodig, dus ik heb hun antwoorden aangepast aan deze korte en lieve functie.

function allowOnlyNumbers(event) {
  if (event.key.length === 1 && /\D/.test(event.key)) {
    event.preventDefault();
  }
}

Het verandert niets aan het gedrag van pijl-, enter-, shift-, ctrl- of tab-toetsen omdat de lengte van de sleuteleigenschap voor die gebeurtenissen langer is dan een enkel teken. Het gebruikt ook eenvoudige reguliere expressies om te zoeken naar niet-cijferige tekens.


Antwoord 5, autoriteit 3%

inputs[5].addEventListener('keydown', enterNumbers);
function enterNumbers(event) {
  if ((event.code == 'ArrowLeft') || (event.code == 'ArrowRight') ||
     (event.code == 'ArrowUp') || (event.code == 'ArrowDown') || 
     (event.code == 'Delete') || (event.code == 'Backspace')) {
     return;
  } else if (event.key.search(/\d/) == -1) {
    event.preventDefault();
  }
}

in dit geval blijft de waarde van het invoerveld intact wanneer een niet-cijferige knop wordt ingedrukt, en toch werken delete, backspace, pijl omhoog-omlaag-links-rechts naar behoren en kan worden gebruikt voor het wijzigen van de digitale ingang.


Antwoord 6, autoriteit 3%

Deze oplossing lijkt goed te werken voor mij. Het bouwt voort op de oplossing van @pavok door ctrl-toetscommando’s te behouden.

document.querySelector("input").addEventListener("keypress", function (e) {
  if (
    e.key.length === 1 && e.key !== '.' && isNaN(e.key) && !e.ctrlKey || 
    e.key === '.' && e.target.value.toString().indexOf('.') > -1
  ) {
    e.preventDefault();
  }
});

Antwoord 7

Ik zal ook MetaKey toevoegen, aangezien ik MacOS gebruik

input.addEventListener("keypress", (e) => {
    const key = e.key;
    if (!(e.metaKey || e.ctrlKey) && key.length === 1 && !/\d\./.test(key)) {
        e.preventDefault();
    }
}

Of u kunt !isNaN(parseFloat(key))

proberen


Antwoord 8

Update over het geaccepteerde antwoord:

Omdat veel eigendommen verouderd raken

(property) KeyboardEvent. which: number @deprecated

u moet gewoon vertrouwen op de eigenschap keyen de rest van de logica zelf maken:

De code staat Enter, Backspace en alle cijfers [0-9] toe, elk ander teken is niet toegestaan.

document.querySelector("input").addEventListener("keypress", (e) => {
  if (isNaN(parseInt(e.key, 10)) && e.key !== "Backspace" && e.key !== "Enter") {
      e.preventDefault();
    }
});

OPMERKING
Hiermee wordt de plakactie uitgeschakeld


Antwoord 9

Op basis van het antwoord van Nrzonline: ik heb het probleem van de meervoudige “.” aan het einde van de invoer door een

. toe te voegen

let lastCharacterEntered

buiten de ingang en dan opKeyPress

e => {
          var allowedChars = "0123456789.";
          function contains(stringValue, charValue) {
            return stringValue.indexOf(charValue) > -1;
          }
          var invalidKey =
            (e.key.length === 1 && !contains(allowedChars, e.key)) ||
            (e.key === "." && contains(e.target.value, "."));
          console.log(e.target.value);
          invalidKey && e.preventDefault();
          if (!invalidKey) {
            if (lastCharacterEntered === "." && e.key === ".") {
              e.preventDefault();
            } else {
              lastCharacterEntered = e.key;
            }
          }
        }

Antwoord 10

Ik had net hetzelfde probleem en ontdekte een alternatieve oplossing met behulp van de validatie-API – werkt zonder zwarte magie in alle belangrijke browsers (Chrome, Firefox, Safari) behalve IE. Deze oplossing voorkomt eenvoudigweg dat gebruikers ongeldige waarden invoeren.
Ik heb ook een fallback voor IE toegevoegd, wat niet leuk is, maar in ieder geval werkt.

Context: functie onInputwordt aangeroepen bij invoergebeurtenissen, setInputValuewordt gebruikt om de waarde van het invoerelement in te stellen, previousInputValuebevat de laatste geldige invoerwaarde (bijgewerkt in setInputValue-aanroepen).

   function onInput (event) {
        const inputValue = event.target.value;
        // badInput supported on validation api (except IE)
        // in IE it will be undefined, so we need strict value check
        const badInput = event.target.validity.badInput;
        // simply prevent modifying the value
        if (badInput === true) {
        // it's still possible to enter invalid values in an empty input, so we'll need this trick to prevent that
            if (previousInputValue === '') {
                setInputValue(' ');
                setTimeout(() => {
                    setInputValue('');
                }, 1);
            }
            return;
        }
        if (badInput === false) {
            setInputValue(inputValue);
            return;
        }
        // fallback case for IE and other abominations
        // remove everything from the string expect numbers, point and comma
        // replace comma with points (parseFloat works only with points)
        let stringVal = String(inputValue)
            .replace(/([^0-9.,])/g, '')
            .replace(/,/g, '.');
        // remove all but first point
        const pointIndex = stringVal.indexOf('.');
        if (pointIndex !== -1) {
            const pointAndBefore = stringVal.substring(0, pointIndex + 1);
            const afterPoint = stringVal.substring(pointIndex + 1);
            // removing all points after the first
            stringVal = `${pointAndBefore}${afterPoint.replace(/\./g, '')}`;
        }
        const float = parseFloat(stringVal);
        if (isNaN(float)) {
            // fallback to emptying the input if anything goes south
            setInputValue('');
            return;
        }
        setInputValue(stringVal);
}

Antwoord 11

Voorkom het typen van niet-alfabet in een specifieke invoer-ID voor pagina’s met meer dan één invoeritem. Het is bruikbaar voor Oracle Apex-ontwikkelaars
— Toevoegen in HTML-header van pagina

<script type="text/javascript">
function validateNumber(event) {
  const activeElmnt = document.activeElement;  
  var keyCode = event.keyCode;
  var excludedKeys = [8, 37, 39, 46];
   if ( activeElmnt.id == "input id in HTML page"){
        if (!((keyCode >= 65 && keyCode <= 90) ||
            (keyCode >= 97 && keyCode <= 122) ||
            (excludedKeys.includes(keyCode)))) {
            console.log("alphabets are not allowed");
            event.preventDefault();
  }
}
  console.log("keycode: " + keyCode + "ActiveElemet: "+activeElmnt.id);
}
</script>

— Toevoegen aan pagina HTML Body-attribuut
onkeydown=”validateNumber(event);”


Antwoord 12

Probeer het:

document.querySelector("input").addEventListener("keyup", function () {
   this.value = this.value.replace(/\D/, "")
});

Other episodes