Angular2输入框仅支持键盘输入数字,鼠标复制粘贴字母未被拦截
Hey Alex, great catch on that paste loophole—your instinct to add the (paste) event binding is totally on the right track! Let’s walk through how to implement this properly to make sure your input stays strictly numeric, even when users paste content.
The Problem with Your Original Setup
Your keypress handler works for keyboard input, but clipboard operations (cut/copy/paste) bypass this check entirely. To lock down the input completely, we need to intercept paste events and validate/clean the clipboard content before it gets inserted.
Correct Implementation
Here’s how to update your code to handle both keyboard input and paste actions:
Step 1: Update the HTML Template
Add the (paste) event binding to your input element:
<input type="text" name="streetCode" ngModel [maxlength]="2" (keypress)="onlyNumber($event)" (paste)="handlePaste($event)" >
Step 2: Update the TypeScript Logic
We’ll refine the existing onlyNumber method (to handle control keys better) and add a handlePaste method to sanitize clipboard content:
onlyNumber(evt: KeyboardEvent): boolean { const charCode = evt.which || evt.keyCode; // Allow control keys (backspace, delete, arrows) so users can edit normally if (charCode > 31 && (charCode < 48 || charCode > 57)) { evt.preventDefault(); return false; } return true; } handlePaste(evt: ClipboardEvent): void { evt.preventDefault(); // Block default paste behavior // Get clipboard content safely const pastedContent = evt.clipboardData?.getData('text') || ''; // Filter out all non-numeric characters const numericContent = pastedContent.replace(/[^0-9]/g, ''); // Truncate to match your maxlength limit (2 characters) const truncatedContent = numericContent.slice(0, 2); // Insert the cleaned content at the cursor position document.execCommand('insertText', false, truncatedContent); }
Why This Works
- Prevents invalid paste: By calling
evt.preventDefault(), we stop raw clipboard content from being inserted directly. - Sanitizes content: The regex
/[^0-9]/gremoves any non-digit characters from the pasted text. - Respects length limits: We truncate the cleaned text to match your
maxlengthvalue, so users can’t paste more than 2 digits. - Preserves user experience: Using
document.execCommand('insertText')keeps the cursor in the correct position, which feels more natural than overwriting the entire input value.
Bonus: Angular Form Control Enhancement
For a more robust, Angular-native solution, consider using a FormControl with built-in validation. This adds a safety net even if any edge cases slip through the event handlers:
import { FormControl, Validators } from '@angular/forms'; // In your component class streetCodeControl = new FormControl('', [ Validators.maxLength(2), Validators.pattern(/^[0-9]*$/) // Ensures only digits are allowed ]);
Then update your HTML to use the form control:
<input type="text" name="streetCode" [formControl]="streetCodeControl" (keypress)="onlyNumber($event)" (paste)="handlePaste($event)" >
This way, even if something bypasses the event handlers, the form control will mark the input as invalid, and you can show error messages to the user.
Your initial idea to add the paste event was spot-on—this implementation just fleshes out the details to make it bulletproof.
内容的提问来源于stack exchange,提问作者Alex Man

