(focusout) ведет себя по-разному в firefox и Chrome

#angular

#angular

Вопрос:

Я выполнял проверку формы на пользовательской кнопке загрузки, добавив красную рамку, если поле оставлено пустым. Откройте приведенную ниже демонстрационную ссылку как в Chrome, так и в Firefox. Нажмите на кнопку загрузки, закройте окно загрузки, а затем щелкните в любом другом месте, чтобы потерять фокус. Будет показана красная рамка, потому что она пуста и помечена как затронутая. Теперь сделайте то же самое в Chrome, красная рамка появится, как только вы нажмете кнопку загрузки, чего я не хочу. Мне нужно поведение, которое я получаю в firefox.

ДЕМО https://stackblitz.com/edit/angular-m2hmua

 <form [formGroup]="cForm" (ngSubmit)="onSubmit()">
  <input type=text placeholder="name" formControlName="name"
  [ngClass]="{'err-border': (cForm.controls.name.errors?.required amp;amp; cForm.controls.name.touched) || cForm.controls.name.errors?.required amp;amp; submitted}" 
  >
  <br><br><br>
  <input type="button" type="file" formControlName="file" id="realInput" style="display: none">
  <button type="button" id="fakeBtn"
  [ngClass]="{'err-border': (cForm.controls.file.errors?.required amp;amp; submitted) || (cForm.controls.file.errors?.required amp;amp; cForm.controls.file.touched)}"
  (focusout)="focusFunction()"
  >Upload</button>
  <span id="text">No file selected</span>
  <br><br><br>
  <button type="submit" >Submit</button>
</form>
  

TS

 import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  cForm: FormGroup;
  submitted = false;
  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.cForm = this.formBuilder.group({
      name: ['', Validators.required],
      file: ['', Validators.required]
    });
    var realInput = document.querySelector('#realInput');
    var fakeBtn = document.querySelector('#fakeBtn');
    var text = document.querySelector('#text');
    fakeBtn.addEventListener("click", function(){
       // @ts-ignore
      realInput.click();

       })
       realInput.addEventListener("change", function(event) {
       // @ts-ignore
      if(realInput.value) {
         // @ts-ignore
        text.innerHTML = event.target.files[0].name;
      } else {
          text.innerHTML = "No file selected";
      }
       });
       fakeBtn.addEventListener("click", ()=> {
         this.submitted = false;
            // @ts-ignore
     document.querySelector('#realInput').value = "";
     this.cForm.controls.file.reset();
       // @ts-ignore
      document.querySelector('#text').innerHTML = "No file";
       });

  }
onSubmit() {
  this.submitted = true;
  if(this.cForm.invalid) {
    return;

  }
  console.log(this.cForm.value);
}

focusFunction(){
  //console.log('inside focus function, touched:',this.cForm.controls.file);
  this.cForm.controls.file.markAsTouched();
}

}
  

Комментарии:

1. Я вижу одинаковое поведение как в FF, так и в Chrome, поведение Chrome (что имеет смысл, поскольку кнопка фактически теряет фокус).

2. Просто чтобы вы знали, Angular имеет свой собственный способ добавления / удаления прослушивателей событий и запросов к DOM — вам не нужно (и не следует) использовать addEventListener or querySelector — это может испортить обнаружение изменений. Вы можете добавлять (click) непосредственно в шаблон и ссылаться на элементы со # ссылками на шаблон и @ViewChild