Angular中被li标签嵌套的输入框达到字符上限时如何自动聚焦下一个输入框
方案1:修改现有逻辑(最快实现)
你当前逻辑的问题是直接取input的相邻兄弟节点,但input外层包裹了li标签,需要先取到父级li,再找li的相邻兄弟节点,最后定位到目标li内的input即可。
修改后的controller代码:
onDigitInput(event: any) { const currentInput = event.target as HTMLInputElement; const parentLi = currentInput.parentElement as HTMLLIElement; let targetInput: HTMLInputElement | null = null; if (event.code !== 'Backspace') { // 非退格场景仅在当前输入框填满时跳转下一个 if (currentInput.value.length === currentInput.maxLength) { const nextLi = parentLi.nextElementSibling as HTMLLIElement | null; targetInput = nextLi?.querySelector('input') || null; } } else { // 退格场景直接跳转上一个,可选清空当前输入框内容 const prevLi = parentLi.previousElementSibling as HTMLLIElement | null; targetInput = prevLi?.querySelector('input') || null; currentInput.value = ''; } targetInput?.focus(); }
方案2:封装为自定义指令(复用性更强)
如果需要在多个场景用到该能力,可以封装为Angular指令,避免重复写逻辑:
- 首先生成指令文件:
ng generate directive digit-auto-focus - 指令代码如下:
import { Directive, HostListener, ElementRef } from '@angular/core'; @Directive({ selector: '[appDigitAutoFocus]' }) export class DigitAutoFocusDirective { constructor(private el: ElementRef<HTMLInputElement>) { } @HostListener('keyup', ['$event']) onKeyUp(event: KeyboardEvent) { const currentInput = this.el.nativeElement; const parentLi = currentInput.parentElement as HTMLLIElement; let targetInput: HTMLInputElement | null = null; if (event.code !== 'Backspace') { if (currentInput.value.length === currentInput.maxLength) { const nextLi = parentLi.nextElementSibling as HTMLLIElement | null; targetInput = nextLi?.querySelector('input') || null; } } else { const prevLi = parentLi.previousElementSibling as HTMLLIElement | null; targetInput = prevLi?.querySelector('input') || null; currentInput.value = ''; } targetInput?.focus(); } }
- 模板中直接使用指令,无需额外绑定事件:
<li *ngFor="let i of [1,2,3,4,5,6]"> <input appDigitAutoFocus class="form-control" placeholder="0" type="text" maxlength="1"> </li>
如果后续input外层的嵌套结构有调整,修改querySelector内的选择器匹配对应结构即可。
内容的提问来源于stack exchange,提问作者Fahad Subzwari
相关产品推荐
相关产品推荐

