标签:应用 javascrip use win https 扩展 listen ring script
最近在项目中涉及表单的情况下,需要对用户输入进行过滤,比如填写用户名的时候不可以使用空格或者特殊符号,这里有几个解决方法:
使用验证器配合输入提示是最直观最容易了解的,但是背后有几个痛点难以解决
该方法需要实现的 process:
由于解决过于繁琐,这里不给出实例。
在习惯了响应式编程后,对于这个场景我们会顺手写下下边的语句
1 @ViewChild(‘usernameInput‘, {static: true}) 2 usernameInputRel: ElementRef; 3 invalidChars: string[] = [‘,‘, ‘.‘, ‘;‘, ‘\[‘, ‘\]‘, ‘`‘]; 4 5 ngAfterViewInit(): void { 6 this.initI18NMessages(); 7 const usernameE = this.usernameInputRel.nativeElement as HTMLInputElement; 8 fromEvent(usernameE, ‘input‘) 9 .pipe( 10 debounceTime(1000), 11 ) 12 .subscribe((e: KeyboardEvent) => { 13 const invalid = asSequence(this.invalidChars).find((c) => usernameE.value.indexOf(c) !== -1); 14 if (invalid !== null) { 15 this.messageService.error(`非法输入: ${invalid}`); 16 } 17 usernameE.value = usernameE.value.replace(/[,.\/;‘\[\]`]/, ‘‘); 18 }); 19 }
让我们审视上边的语句,该方法需要实现的 process:
我们将的 Javascript 代码中的监听模式应用到元素上,当输入的值在禁止范围内,则阻止默认行为,我们不会使用 stopPropagation() 方法,因为它阻止了事件冒泡,如果之后需要在它的扩展父元素上监听事件,代码将会需要修改;同时应该注意到,由于我们没有删除值的步骤,所以需要禁用粘贴功能;
1 @ViewChild(‘passwordInput‘, {static: true}) 2 passwordInput: ElementRef; 3 4 ngAfterViewInit(): void { 5 const input = this.passwordInput.nativeElement as HTMLInputElement; 6 input.addEventListener(‘paste‘, ev => ev.preventDefault()); 7 input.addEventListener(‘keydown‘, ev => { 8 const regExp: RegExp = new RegExp([‘\\‘, ‘,‘, ‘/‘, ‘\"‘].join(‘|‘), ‘gi‘); 9 if (regExp.exec(ev.key) !== null) { 10 ev.preventDefault(); 11 } 12 }); 13 }
让我们审视这次的实现并与上边对比
如果需要在多个表单元素上应用上边的代码,代码将变得非常臃肿,因此我们将借助 Angular 的 Directive ,先构想一些组件中需要的实现:
那么,当应用到 Input 元素上,它应该是这样子的:
<input [crxBlockKeys]="blockNameChars" type="text" />
blockNameChars 是从 component 获得的,它的值是:
const blockNameChars: string[] = [‘ ‘, ‘/‘, ‘\‘‘];
或者这样子应用:
<input [crxBlockKeys]="[‘ ‘, ‘\\‘, ‘\‘‘]" type="text" />
现在让我们手动实现:
1 @Directive({selector: ‘[crxBlockKeys]‘}) 2 export class BlockKeysDirective { 3 @Input(‘crxBlockKeys‘) 4 blockKeys: string[]; 5 6 /** 7 * @see DocumentAndElementEventHandlersEventMap.paste 8 * @param e ClipboardEvent 9 */ 10 @HostListener(‘paste‘, [‘$event‘]) 11 preventPaste(e: Event): void { 12 e.preventDefault(); 13 } 14 15 /** 16 * @see WindowEventMap.keydown 17 * @param e KeyboardEvent 18 */ 19 @HostListener(‘keydown‘, [‘$event‘]) 20 preventEmptyInput(e: KeyboardEvent): void { 21 const regExp: RegExp = new RegExp(this.blockKeys.join(‘|‘), ‘gi‘); 22 if (regExp.exec(e.key) !== null) { 23 e.preventDefault(); 24 } 25 } 26 }
现在我们的代码得到了复用,当需要使用的时候,只需要在 input 内加入这个属性,并传入禁止的数值组;
如果你抗拒写转义字符,可以使用下边的 Directive,我们更改传入数值组为 Code (eg: [‘Semicolon‘, ‘NumpadDivide‘, ‘Space‘]):
1 @Directive({selector: ‘[crxBlockCodes]‘}) 2 export class BlockCodesDirective { 3 @Input(‘crxBlockCodes‘) 4 blockCodes: string[]; 5 6 /** 7 * @see DocumentAndElementEventHandlersEventMap.paste 8 * @param e ClipboardEvent 9 */ 10 @HostListener(‘paste‘, [‘$event‘]) 11 preventPaste(e: Event): void { 12 e.preventDefault(); 13 } 14 15 /** 16 * @see WindowEventMap.keydown 17 * @param e KeyboardEvent 18 */ 19 @HostListener(‘keydown‘, [‘$event‘]) 20 preventEmptyInput(e: KeyboardEvent): void { 21 const regExp: RegExp = new RegExp(this.blockCodes.join(‘|‘), ‘gi‘); 22 if (e.code.match(regExp).length !== 0) { 23 e.preventDefault(); 24 } 25 } 26 }
让我们审视这次的实现并与上边对比
我们的实现需要的步骤变化为: 5 > 3 > 1 ,这个改变是巨大的,同时,代码的复用性与稳定性也有了很大改善
你也可以使用这个在线工具快速获取 key 与 code 值
Angular 输入中的禁止特定输入值--Validator 与 Directive 实现
标签:应用 javascrip use win https 扩展 listen ring script
原文地址:https://www.cnblogs.com/siweipancc/p/angulr_forbid_values_with_directive.html