Angular表单提交时NgModelGroup内无效输入自动聚焦失效问题
问题根因
Angular 中
NgModelGroup对应的DOM元素在校验失败时,也会被自动添加.ng-invalid样式类。你原有逻辑中使用querySelectorAll(".ng-invalid")获取到的第一个元素,大概率是上层的NgModelGroup容器,而非内部可聚焦的输入框,容器本身不支持focus方法,因此分组内的输入项校验失败时无法正常触发聚焦。
修复后代码
import { Directive, Input, HostListener, ElementRef } from "@angular/core"; import { NgForm } from "@angular/forms"; declare var $: any; @Directive({ selector: "[accessible-form]" }) export class AccessibleForm { @Input("form") form: NgForm; constructor(private el: ElementRef) {} @HostListener("submit", ["$event"]) onSubmit(event) { event.preventDefault(); if (!this.form.valid) { // 仅选中可聚焦的输入类无效元素,排除NgModelGroup等容器元素 const invalidInputs = this.el.nativeElement.querySelectorAll( "input.ng-invalid, select.ng-invalid, textarea.ng-invalid" ); if (invalidInputs?.length) { const firstInvalid = invalidInputs[0]; // 修复滚动位置取值错误,预留20px顶部边距避免输入框贴顶 $("html,body").animate({ scrollTop: $(firstInvalid).offset().top - 20 }, "slow"); firstInvalid.focus(); } } } }
修改说明
- 调整选择器规则,仅匹配输入框、下拉框、文本域三类可聚焦的表单元素,避免命中
NgModelGroup容器 - 修复原有滚动逻辑中直接传入元素集合的错误,取第一个无效元素的位置计算滚动距离
- 补充元素存在性判断,避免无无效输入项时控制台报错
使用方式和原有逻辑一致,无需调整业务侧表单代码。
内容的提问来源于stack exchange,提问作者Harman
相关产品推荐
相关产品推荐

