import { Directive, ElementRef, Input } from '@angular/core'; import { HostListener } from '@angular/core'; @Directive({ // tslint:disable-next-line: directive-selector selector: '[number-only]' }) export class NumberOnlyDirective { @Input() precision: number; constructor(private element: ElementRef) {} @HostListener('keydown', ['$event']) onKeyDown(e: KeyboardEvent) { const val = (e.target as any).value; const key = e.key; const checkKeys = ['.', '-', '%']; const selectionVal = this.getSelectionValue(e.target); if (val && checkKeys.indexOf(key) > -1 && val.indexOf(key) > -1 && !(selectionVal && selectionVal.indexOf(key) > -1) ) { e.preventDefault(); } if ( [46, 8, 9, 27, 13, 110, 190, 173].indexOf(e.keyCode) !== -1 || // 允许全选: Ctrl+A (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) || // 允许复制: Ctrl+C (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) || // 允许粘贴: Ctrl+V (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) || // 允许剪切: Ctrl+X (e.keyCode === 88 && (e.ctrlKey || e.metaKey)) || // 允许: home(头), end(尾), left(左移), right(右移) (e.keyCode >= 35 && e.keyCode <= 39) || e.keyCode === 189 ) { // let it happen, don't do anything return; } // 确保数字以外的案件被拒绝执行默认动作 if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { e.preventDefault(); } // 判断当前小数精度 if (val.indexOf('.') > -1 && this.precision) { const curPos = (e.target as any).selectionStart; const selectionEnd = (e.target as any).selectionEnd; const _precision = val.split('.')[1].length; const dotPos = val.indexOf('.'); if (curPos > dotPos) { const selectionText = val.substring(curPos, selectionEnd); if (_precision - selectionText.length >= Number(this.precision)) { e.preventDefault(); return false; } } } } private getSelectionValue(target) { const start = (target as any).selectionStart; const end = (target as any).selectionEnd; return target.value.substring(start, end); } // @HostListener('compositionstart', ['$event']) onCompositionstart(e: KeyboardEvent) { // e.preventDefault(); // console.log('compositionstart'); // console.log(e); // e.returnValue = false; // } }