无法输入HTML表单文本/密码/数字输入字段具有Unity WebGL构建的网站

问题描述

我们正在使用Angular 9开发网站。 我们还集成了Unity3D WebGL构建。 当我尝试在其中一张表单的文本/密码/数字输入字段中键入内容时,它什么也没写,并且该字段似乎没有收到输入;同样,我将字段绑定到的变量不会用新值更新。 奇怪的是:

  • 我可以选择输入字段(它会突出显示,就像我可以开始键入一样)
  • 我可以在字段上进行CTRL+C,并且将复制的内容粘贴到了其他地方
  • 我可以使用type="number"箭头选择器设置字段的值
  • 我不能键盘上的字段中输入
  • 我可以按预期与其他表单标签(例如<select>
  • )进行交互
  • 如果我重新加载页面,它通常会按预期开始工作,我可以在字段中输入

这是我的登录表单中的代码(上面的component.ts,下面的模板HTML)

import { Component,OnInit } from '@angular/core';
import { AuthService } from '../auth.service'
import { first } from 'rxjs/operators';
import { Router,ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-login',templateUrl: './login.component.html',styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {

  email: string = "";
  password: string = "";

  returnUrl: string = "home";

  constructor(private router: Router,private route: ActivatedRoute,private authService: AuthService) { }

  ngOnInit(): void {
    let tmpReturnUrl = this.route.snapshot.queryParams["returnUrl"];
    if (tmpReturnUrl != undefined)
    {
      console.log("true");
      this.returnUrl = tmpReturnUrl;
    }
    else
      console.log("false");

    setInterval(() => {
      console.log("EMAIL: " + this.email);
    },1000);
  }

  onSubmit(){
    this.authService.login(this.email,this.password)
    .pipe(first())
    .subscribe(
      result => {
        console.log("CAIOAOAOAOOA");
        this.router.navigate([this.returnUrl]);
      },err => console.log(err)
    );
  }
}
<div class="card z-depth-5 w-50">
  <div class="card-body">
    <div class="card-title">Log in</div>
    <div class="card-text">
      <form #companyLoginForm="ngForm" (ngSubmit)="onSubmit()">
        <mat-form-field>
          <mat-label>Email: </mat-label>
          <input matInput required type="text" name="email" id="email" [(ngModel)]="email">
        </mat-form-field>
        <mat-form-field>
          <mat-label>Password: </mat-label>
          <input matInput required type="password" name="password" id="password" [(ngModel)]="password">
        </mat-form-field>
        <button type="submit" [disabled]="!companyLoginForm.form.valid">Login</button>
      </form>
      <a routerLink="/company-register">
        <button mdbBtn type="button" color="primary" class="relative waves-light">Sign Up</button>
      </a>
    </div>
  </div>
</div>

在这里,我还使用type="number"<select>的另一种形式的代码(上面的component.ts,下面的模板HTML)

import { Component,OnInit,Output } from '@angular/core';
import { BlockFormService } from '../block-form.service';
import { BlockData } from '../blockCardData';
import { BlockUtilsService } from '../block-utils.service';
import { ApiService } from '../../core/api.service'
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-block-form',templateUrl: './block-form.component.html',styleUrls: ['./block-form.component.less']
})
export class BlockFormComponent implements OnInit {

  updateComplete : Boolean = false;
  materials : string[];
  products : string[];
  varieties : string[];
  nations : string[];
  // companies : {name: string,id: string}[] = [];
  company : string = "";
  colors : string[] = ["White","Grey","Black","brown","Red","Green","Yellow","Blue"];
  blockData : BlockData = {_id : "",blockId: "",company: "",material: "",product: "",variety: "",color: "",nation: "",modelName : "",imagePreview : "",price: null,blockNumber: "",length: null,height: null,width: null,weight: null
  };
  imagePreview: File = null;
  zipFile: File = null;

  invalidUpload: boolean = false;

  constructor( private blockFormService: BlockFormService,public blockUtils: BlockUtilsService,private companiesUtils: ApiService )
  { }

  ngOnInit(): void {
    this.materials = this.blockUtils.getMaterials();
    this.colors = this.blockUtils.getColors();
    this.companiesUtils.getLoggedCompany().subscribe(companiesResult => {
      this.blockData.company = companiesResult._id;
      this.company = companiesResult.name;
    });
  }

  onImageSelected(event){
    console.log(event.target.files[0]);
    if (event.target.files[0].type === "image/png")
    {
      if (this.invalidUpload)
        this.invalidUpload = false;
      this.imagePreview = event.target.files[0];
    }
    else{
      if (!this.invalidUpload)
        this.invalidUpload = true;
      event.target.value = null;
    }
  }

  onMaterialSet(newMaterial): void{
    console.log("Material set");
    this.products = this.blockUtils.getProducts(newMaterial);
    //console.log(this.products);
    // if (this.products.length > 0)
    //   this.blockData.product = this.products[0];
    // else
      this.blockData.product = "";

    this.onProductSet(this.blockData.product);
  }

  onProductSet(newProduct): void{
    console.log("Product set");
    this.varieties = this.blockUtils.getvarieties(this.blockData.material,newProduct);
    // if (this.varieties.length > 0)
    //   this.blockData.variety = this.varieties[0];
    // else
    this.blockData.variety = "";

    this.nations = this.blockUtils.getNations(this.blockData.material,this.blockData.product);
    if (this.nations.length > 0)
      this.blockData.nation = this.nations[0];
    else
      this.blockData.nation = "";

    this.onVarietySet(this.blockData.variety);
  }

  onVarietySet(newVariety): void{
    console.log("Variety set");
    // this.nations = this.blockUtils.getNations(this.blockData.material,this.blockData.product);
    // if (this.nations.length > 0)
    //   this.blockData.nation = this.nations[0];
    // else
    //   this.blockData.nation = "";
  }

  onSubmit(blockForm : NgForm,imageField,zipField): void{
    this.blockFormService.sendBlock(this.blockData,this.imagePreview,this.zipFile)
    .subscribe(res => {
      console.log("Sent!");
      this.updateComplete = true;
    });

    this.blockData = {
      _id: "",modelName: "",imagePreview: "",weight: null
    };
    blockForm.resetForm();
    imageField.value = null;
    zipField.value = null;
    this.imagePreview = null;
    this.zipFile = null;
  }
}
<div class="form-group">


  <div class="text-center" *ngIf='updateComplete'>
    Block added successfuly
  </div>

  <form #blockForm="ngForm" (ngSubmit)="onSubmit(blockForm,zipField)">
    <div class="container">
      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Company: </mat-label>
            <!-- <mat-select required [(ngModel)]="blockData.company" name="company-field"
              id="company-field">
              <mat-option selected [value]="company.id">{{company.name}}</mat-option>
            </mat-select> -->
            <input matInput disabled [value]="company" type="text" name="company-field" id="company-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Material: </mat-label>
            <mat-select #matField required [(ngModel)]="blockData.material" name="kind-field"
              id="kind-field" (selectionChange)="onMaterialSet(blockData.material)">
              <mat-option *ngFor="let mat of materials" [value]="mat">{{mat}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Product: </mat-label>
            <mat-select required [(ngModel)]="blockData.product" name="product-field"
              id="product-field" (selectionChange)="onProductSet(blockData.product)">
              <mat-option *ngFor="let prod of products" [value]="prod">{{prod}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Block Number: </mat-label>
            <input matInput required [(ngModel)]="blockData.blockNumber" type="text" name="blockNumber-field" id="blockNumber-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Variety: </mat-label>
            <mat-select required [(ngModel)]="blockData.variety" name="variety-field" id="variety-field"
              placeholder="Variety" (selectionChange)="onVarietySet(blockData.variety)">
              <mat-option *ngFor="let variety of varieties" [value]="variety">{{variety}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <!-- <label for="color-field">Color: </label> -->
          <mat-form-field>
            <mat-label>Color: </mat-label>
            <mat-select required [(ngModel)]="blockData.color" name="color-field" id="color-field" placeholder="Color">
              <mat-option *ngFor="let col of colors" [value]="col">{{col}}</mat-option>
            </mat-select>
          </mat-form-field>
          <!-- <input #colField required [(ngModel)]="blockData.color" type="text" name="color-field" id="color-field" placeholder="Color"> -->
          <!-- <color-circle #colorField [colors]='["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#009688","#4caf50","#8bc34a","#cddc39","#ffeb3b","#ffc107","#ff9800","#ff5722","#795548","#607d8b"]' name="color-field" id="color-field" (onChange)="blockData.color = $event.color.hex"></color-circle> -->
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Nation: </mat-label>
            <!-- <mat-select required [(ngModel)]="blockData.nation" name="nation-field"
              id="nation-field">
              <mat-option *ngFor="let nat of nations" [value]="nat">{{nat}}</mat-option>
            </mat-select> -->
            <input matInput disabled [(ngModel)]="blockData.nation" type="text" name="nation-field" id="nation-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Price: </mat-label>
            <input matInput required [(ngModel)]="blockData.price" type="number" name="price-field" id="price-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Length: </mat-label>
            <input matInput required [(ngModel)]="blockData.length" type="number" name="length-field" id="length-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Width: </mat-label>
            <input matInput required [(ngModel)]="blockData.width" type="number" name="width-field" id="width-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Height: </mat-label>
            <input matInput required [(ngModel)]="blockData.height" type="number" name="height-field" id="height-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Weight: </mat-label>
            <input matInput required [(ngModel)]="blockData.weight" type="number" name="weight-field" id="weight-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <div class="file-field">
            <div class="btn btn-primary btn-sm float-left">
              <label for="image-field">Upload preview image: </label>
              <input #imageField (change)="onImageSelected($event)" name="image-field" id="image-field" type="file" accept=".png,image/png" placeholder="Upload your file">
            </div>
          </div>
        </div>
        <div class="col-3">
          <div class="file-field">
            <div class="btn btn-primary btn-sm float-left">
              <label for="zip-field">Upload models' zip: </label>
              <input #zipField (change)="zipFile = $event.target.files[0];" name="zip-field" id="zip-field" type="file" placeholder="Upload your file">
            </div>
          </div>
        </div>
      </div>
      <button type="submit" [disabled]="!blockForm.form.valid || imagePreview == null || zipFile == null || blockData.company === ''">Submit</button>
    </div>
  </form>
</div>

我希望我已经足够清楚了,感谢您的帮助:)

解决方法

最后,我找到了问题的根源。在我们的网站中,我们已经集成了Unity3D WebGL构建,并且,如果我从带有Unity的网页移至登录页面,则Unity进程仍在运行。 Unity专注于键盘的每个输入,因此它捕获了所有输入。

更改页面时,我们通过quitting the Unity application解决了该问题。这样,输入字段可以再次从键盘接收输入。

另一种解决方案,也许是(我还没有测试过),可能是不让Unity获得输入,如this Unity forum's thread中所述或通过设置 {{3} } 设置为false。