
⚙️ Hur du begränsar oönskad teckeninmatning i INPUT med JavaScript
Registreringsformulär, telefonfält, katalogsökning: användaren klickar på ett INPUT och skriver vad som helst. Bokstäver där du förväntar dig siffror. Specialtecken i ett ordernummer. Emoji i ett e-postfält. Resultatet: skräp i databasen, trasiga frågor, backend-validering som misslyckas med ett fel.
Problemet löses på frontend-sidan med 15 rader kod. Inga plugins, inga bibliotek, bara vanlig JavaScript eller ett par HTML-attribut. Nedan följer tre fungerande tillvägagångssätt: från snabb HTML5 till finkornig filtrering på keydown, med färdiga exempel för vanliga scenarier.
💡 Snabb översikt:
- Vi undersöker när HTML-attributen
pattern,inputmodeochtyperäcker, och när JavaScript behövs - Vi skriver ett "endast siffror"-filter i jQuery och ren JS, båda versionerna med rad-för-rad-genomgång
- Vi lägger till skydd mot inklistring via Ctrl+V och snabbmenyn
- Vi bygger en universell mallfunktion för alla begränsningar: bokstäver, latinska tecken, anpassade masker
HTML5: vad du kan göra utan en enda rad JavaScript
Det enklaste och mest pålitliga sättet att begränsa inmatning är att tala om för webbläsaren exakt vad du förväntar dig i ett fält. Moderna webbläsare förstår tre nyckelattribut som täcker de flesta vanliga uppgifter.
type, det primära filtret. type="number" tillåter endast siffror, minus och decimalavgränsare. type="tel" visar ett numeriskt tangentbord på mobila enheter. type="email" kontrollerar efter @ vid formulärinskick. type="url" kräver ett protokoll. Detta blockerar inte inmatning helt, men det ger rätt skärmtangentbord och grundläggande validering vid inskick.
pattern, ett reguljärt uttryck på fältet. Attributet accepterar ett regex och validerar värdet vid formulärinskick:
1 <input type="text" pattern="[0-9]{6}" placeholder="Six digits" title="Exactly 6 digits">
Webbläsaren blockerar inskick om värdet inte matchar mönstret. Nackdelen: pattern förhindrar inte inmatning av otillåtna tecken; det validerar bara resultatet. Användaren kan skriva "abc", och får bara se felet när de försöker skicka formuläret.
inputmode, rätt tangentbord på mobilen. inputmode="numeric" öppnar ett numeriskt tangentbord men förbjuder inte inmatning av bokstäver. inputmode="decimal" lägger till en avgränsare. Användbart i kombination med ett JavaScript-filter: tangentbordet är redan korrekt, och JS hanterar resten.
Vad du ska välja. Om du behöver faktiskt förhindra inmatning av otillåtna tecken i realtid räcker inte HTML-attributen. Låt oss gå vidare till JavaScript.
JavaScript: blockera tangenttryck via keydown
keydown-metoden fångar varje tangenttryck innan tecknet visas i fältet. Om tangenten inte finns på vitlistan förhindrar event.preventDefault() den.
Alternativ 1: jQuery, endast siffror
Koden kopplas till ett INPUT via id, tillåter siffror och servicetangenter (backsteg, pilar, Tab) och blockerar allt annat:
1 $(document).ready(function() { 2 $("#phone_input").keydown(function(event) { 3 // Service keys — let them through 4 if (event.keyCode === 46 || event.keyCode === 8 || 5 event.keyCode === 9 || event.keyCode === 27 || 6 (event.keyCode === 65 && event.ctrlKey === true) || 7 (event.keyCode >= 35 && event.keyCode <= 39)) { 8 return; 9 } 10 // Block everything except digits (main block and numpad) 11 if ((event.keyCode < 48 || event.keyCode > 57) && 12 (event.keyCode < 96 || event.keyCode > 105)) { 13 event.preventDefault(); 14 } 15 }); 16 });
Här är vad som händer rad för rad: keyCode 46 (Delete), 8 (Backsteg), 9 (Tab), 27 (Escape), 65 + Ctrl (markera allt), 35..39 (Home, End, pilar). Sedan kommer huvudblocket siffror 48..57 (0..9) och numeriskt tangentbord 96..105. Allt som inte faller inom dessa intervall får preventDefault.
Fullständig key code-tabell på Cambia Research.
Alternativ 2: ren JavaScript, endast siffror
Samma sak utan jQuery, med onkeypress. Denna version är mer kompakt och drar inte in ett bibliotek:
1 document.getElementById("phone_input").onkeypress = function(event) { 2 event = event || window.event; 3 if (event.charCode && (event.charCode < 48 || event.charCode > 57)) { 4 return false; 5 } 6 };
charCode kontrollerar att händelsen har ett utskrivbart tecken; servicetangenter (pilar, backsteg) passerar automatiskt eftersom deras charCode är 0. Siffror: 48..57, allt annat returnerar false.
Viktigt: keyCode anses vara föråldrat. I modern kod är det bättre att använda event.key, som returnerar en sträng med tangentens namn och inte beror på tangentbordslayout:
1 element.addEventListener("keydown", function(event) { 2 // Allow digits, Backspace, Delete, arrows, Tab 3 const allowedKeys = [ 4 "Backspace", "Delete", "Tab", "Escape", 5 "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", 6 "Home", "End" 7 ]; 8 if (allowedKeys.includes(event.key)) return; 9 // Ctrl+A / Ctrl+C / Ctrl+V 10 if (event.ctrlKey) return; 11 // Only digits 12 if (!/^[0-9]$/.test(event.key)) { 13 event.preventDefault(); 14 } 15 });
event.key-metoden är mer lättläst och kräver inte att man memorerar numeriska koder. Men för att stödja äldre webbläsare fungerar keyCode-versionen ovan fortfarande.
Blockera inklistring: fånga Ctrl+V och snabbmenyn
keydown fångar tangenttryck, men användaren kan klistra in text via Ctrl+V eller högerklick → "Klistra in". De kopierade "abc123" till ett fält för endast siffror, och hälften slank igenom.
Lösningen är input-händelsen. Den utlöses efter ALLA ändringar av fältvärdet: manuell inmatning, inklistring, autofyll, dra-och-släpp av text. Vi filtrerar slutvärdet med ett reguljärt uttryck:
1 document.getElementById("digits_only").addEventListener("input", function(event) { 2 this.value = this.value.replace(/[^0-9]/g, ""); 3 });
Det är allt. En rad, och inte en enda icke-siffra kommer att passera genom fältet, oavsett hur den kom dit. För bokstäver: replace(/[^a-zA-Zа-яА-ЯёЁ]/g, ""). För latinska tecken: replace(/[^a-zA-Z]/g, "").
Kombinerad metod (den gyllene medelvägen). keydown ger omedelbar återkoppling (tangenten "trycks inte ned"), medan input skyddar mot inklistring. Använd båda hanterarna:
1 const field = document.getElementById("digits_only"); 2 3 field.addEventListener("keydown", function(event) { 4 const allowed = ["Backspace", "Delete", "Tab", "Escape", 5 "ArrowLeft", "ArrowRight", "Home", "End"]; 6 if (allowed.includes(event.key)) return; 7 if (event.ctrlKey) return; 8 if (!/^[0-9]$/.test(event.key)) event.preventDefault(); 9 }); 10 11 field.addEventListener("input", function() { 12 this.value = this.value.replace(/[^0-9]/g, ""); 13 });
Den första hanteraren stoppar otillåtna tangenttryck direkt. Den andra rensar upp rester efter inklistring och autofyll.
Färdig mall för alla begränsningar
Låt oss bygga en funktion som tar ett INPUT och ett reguljärt uttryck för tillåtna tecken. Den fungerar för telefonnummer, postnummer, inloggningar, SKU-sökning:
1 function restrictInput(element, allowedPattern) { 2 element.addEventListener("keydown", function(event) { 3 const serviceKeys = [ 4 "Backspace", "Delete", "Tab", "Escape", 5 "ArrowLeft", "ArrowRight", "Home", "End" 6 ]; 7 if (serviceKeys.includes(event.key)) return; 8 if (event.ctrlKey && ["a", "c", "v", "x", "z"].includes(event.key.toLowerCase())) return; 9 if (!allowedPattern.test(event.key)) event.preventDefault(); 10 }); 11 12 element.addEventListener("input", function() { 13 // Build a global pattern from the provided one and clean 14 const globalPattern = new RegExp( 15 allowedPattern.source.replace("^", "").replace("$", ""), 16 "g" 17 ); 18 // Remove everything that does NOT match the pattern 19 const inverted = new RegExp( 20 "[^" + allowedPattern.source.slice(1, -1) + "]", "g" 21 ); 22 this.value = this.value.replace(inverted, ""); 23 }); 24 }
Användning:
1 // Digits only 2 restrictInput(document.getElementById("phone"), /^[0-9]$/); 3 // Latin letters only without spaces 4 restrictInput(document.getElementById("login"), /^[a-zA-Z]$/); 5 // Letters and digits 6 restrictInput(document.getElementById("postal"), /^[a-zA-Z0-9]$/);
Funktionen är inte beroende av jQuery, fungerar i alla moderna webbläsare och täcker tre scenarier: manuell inmatning (keydown), inklistring (input), autofyll (input).
Observera: keydown utlöses inte på virtuella tangentbord på vissa mobila enheter; där förblir input det enda skyddet. Därför är två hanterare tillsammans inte redundans utan nödvändighet.
Videon ovan är en genomgång av formulärvalidering i ren JavaScript från Web Dev Simplified. Den täcker det inbyggda Constraint Validation API:et, anpassade felmeddelanden och stil för ogiltiga fält, ett utmärkt komplement till metoderna som beskrivs här.
⁉️🤔 Vanliga frågor
Varför inte bara använda type="number"?
type="number"tillåter inmatning aveochE(exponent), plus, minus och punkt. Alla dessa är giltiga tecken för flyttal och exponentiell notation. För ett telefonfält eller postnummer är de onödiga. Dessutom hanterar webbläsare icke-numerisk inmatning olika: vissa släpper igenom det tyst, andra visar ett fel först vid inskick.
Kan man helt blockera inklistring via Ctrl+V?
Att blockera inklistring helt är dålig praxis. Det förstör användarupplevelsen och skyddar inte mot andra inklistringsmetoder (snabbmeny, dra-och-släpp). Rätt tillvägagångssätt: tillåt inklistring, men rensa omedelbart resultatet via en
input-hanterare, som visas i avsnittet ovan.
Vad sägs om webbläsarens autofyll?
Autofyll utlöses före
keydownochinput; webbläsaren infogar värdet direkt.input-hanteraren fångar även detta fall: värdet visas i fältet och filtreras sedan omedelbart. Om autofyll stör (infogar bokstäver i ett telefonfält), lägg till attributetautocomplete="off"på INPUT:en.
Fungerar detta på mobila enheter?
Ja, men med en brasklapp: virtuella tangentbord genererar inte alltid
keydownmed förväntadkeyCodeochkey.input-hanteraren fungerar tillförlitligt överallt. På mobil, sättinputmode="numeric"ellerinputmode="decimal"på INPUT:en; användaren får rätt tangentbord även omkeydown-filtret inte utlöses.
Hur förbjuder man mellanslag?
Lägg till mellanslag i klassen för otillåtna tecken:
replace(/[^0-9a-zA-Z]/g, "")tar bort allt utom siffror och latinska bokstäver, inklusive mellanslag. Eller explicit:this.value = this.value.replace(/\s/g, "")tar bort alla mellanslag, tabbar och radbrytningar.
Vilken metod du ska välja för din uppgift

Om formuläret är enkelt och ett par felaktiga tecken inte orsakar kritisk skada, använd HTML5: type, pattern och inputmode täcker grundläggande scenarier utan en enda rad JS. Snabbt, native, inga beroenden.
Om realtidskontroll och omedelbar reaktion på varje tangenttryck är viktigt, använd kombinationen keydown + input. Den första blockerar tangenttryck, den andra rensar upp inklistringskonsekvenser. Den universella mallfunktionen från avsnittet ovan anpassas till vilket fält som helst på en minut.
Huvudregeln: blockera inte inklistring helt. Det irriterar användare och ger inget verkligt skydd. Rensa resultatet efter inklistring istället för att förbjuda det.



