点击元素时,Angular如何将焦点集中在输入框上

3
我已经附上了下面的 StackBlitz。

https://stackblitz.com/edit/angular-dgx3pe

我试图实现的是,当点击标签元素时,它应该聚焦于输入框。因此,input:focus类被激活。我相信这可以通过JavaScript / jQuery来实现。但我更喜欢使用Angular的方式来实现这一点。
简而言之,我正在尝试做以下两件事:
  • 当单击标签时,将焦点放在输入元素上。
  • 当焦点转移到另一个输入元素并且前一个元素不为空(如果键入了某些值),则标签应保持其位置在顶部。
HTML
<input class="input" type="text">
<label class="label">Name</label>

<div>
<input class="input" type="text">
<label class="label">Name</label>
</div>

CSS (层叠样式表)
p {
  font-family: Lato;
}
.input
{
  border:none;
  border-bottom:1px solid grey;
  outline:none;
   margin-top:20%;
}
.input:focus
{
    border-bottom:1px solid orange;
}
.label
{
  position:relative;
 left:-170px;
}
.input:focus + .label
{
   bottom:20px;
}

你想要标签在元素的第一个焦点事件后成为常量吗? - Prashant Pimpale
为什么不尝试使用Mat-Input - Prashant Pimpale
如果输入没有值,标签应该回到原来的位置。但是,如果它有一些值,它应该是恒定的,当值被删除并且焦点离开时,它应该返回到原始位置。感谢建议,但我正在尝试避免使用材料。 - Sathya Narayanan GVK
3个回答

3
  1. 在html中,添加对输入文本的引用 - #firstNameField,并在标签的点击事件上添加一个方法 - (click)="focusOnFirstName()"
  2. 将原始答案翻译成“最初的回答”
    <input #firstNameField class="input" type="text">
    <label class="label" (click)="focusOnFirstName()">First Name</label>

  1. 在你的组件中声明ViewChild,并实现一个点击标签字段的方法。
注:Original Answer翻译成"最初的回答"。
      @ViewChild("firstNameField") firstNameField;

      focusOnFirstName(){
        this.firstNameField.nativeElement.focus();
      }



谢谢,这几乎解决了我的问题,除了第二部分。当有值时,标签应保持在顶部。当移除时,它应该回到原始位置。 - Sathya Narayanan GVK

1
你可以使用纯标记语言实现这个功能。你需要给输入框添加一个id属性,并在标签中添加一个for属性。
<input class="input" type="text" id="firstName">
<label class="label" for="firstName" >First Name</label>

这只是HTML规范的一部分 - 标签可以与输入框相关联 - 开箱即用的功能是,单击标签会将焦点设置到其关联的输入框。为此,idfor属性必须匹配。

对于您问题的第二部分,并且要重复使用CSS类 - 添加匹配变量到您的组件中。使用ngClass在变量具有值时添加.go-top类。

在组件中 -

firstName: string;

然后在HTML中 -
  <input class="input" type="text" id="firstName" [(ngModel)]="firstName">
  <label class="label" for="firstName" [ngClass]="{'go-top': firstName}">First Name</label>

谢谢,现在我已经能够完成第一部分了...但是你能解释一下它的工作原理吗?另外,当输入有值时,你能帮助我让标签保持在顶部吗? - Sathya Narayanan GVK
谢谢,它解决了我的问题。只有一件事,您能否建议我是否有一种方法可以动态地创建输入而不必为每个输入创建单独的变量? - Sathya Narayanan GVK
[(ngModel)] 是跟踪您的输入值的完美解决方案。 确保导入表单模块,以便您不会收到未知指令错误:import { FormsModule } from '@angular/forms' - rmrouse88

1
我从制作更“Angular”解决方案的角度来看待您的条件样式请求。 为此,您应该专注于将输入/标签组合成自定义输入组件。 创建具有原始元素的组件作为起始模板后,您可以更有效地执行以下操作。
基本策略是使用Angular的[class]属性绑定或[NgStyle]指令有条件地应用样式。
1. 在模板中对输入元素进行ViewChild查询 2. 在模板中的输入元素上添加事件监听器 3. 每当检测到keyup事件时,它将触发检查您的<input>字段值并更新表示字段是否为空的类属性。 4. 更改检测将触发,[NgClass]或[class]绑定将触发更新元素的类。
//component.ts

import { Component, Input, ViewChild, ElementRef } from '@angular/core'

@Component({
  selector: 'app-input',
  styleUrls: ['./input.component.css'],
  templateUrl: './input.component.html'
})

export class InputComponent{
  @Input() labelName: string = "Your Label Here"
  @ViewChild("input") myInput:ElementRef<any> //ViewChild query

  empty: Boolean = true; // this property will track whether input value is truthy

  isEmpty(){ // attached to keyup event on input element in your template file

   if (this.myInput.nativeElement.value){
      this.empty = false;
    } else{
      this.empty = true;
    }
  }

  styles(){ // attached to the [ngClass] directive binding on input element in template file
    return {
      'empty': this.empty ? true: false,
      'not-empty': this.empty ? false: true
    }
  } 

}


//component.html with [ngClass] directive

<label for="my-input" #label> {{ labelName }}
<input type="text" id="my-input" [ngClass]="styles()" (keyup) = "isEmpty()" #input>


//component.html with [style] property binding
// in this instance, empty is a reference to the property in the .ts file

<label for="my-input" #label> {{ labelName }}
<input type="text" id="my-input" [class.empty]="empty" #input>

感谢您的时间。如果您将其制作为指令,我们如何将其附加到表单上?在我的情况下,这是一个响应式表单。特定的输入指令将要求一个表单组,该表单组仅在父组件中可用。有没有办法克服这个问题? - Sathya Narayanan GVK
附上的代码似乎有点混乱,你能分享一下 Stackblitz 吗? - Sathya Narayanan GVK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接