【问题标题】:Angular focus on input while clicking an element单击元素时对输入的角度关注
【发布时间】:2019-06-01 05:23:36
【问题描述】:

我在下面附上了stackblitz

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

我想要实现的是在单击标签元素时它应该专注于输入。因此 input:focus 类被激活。我相信它可以通过 javascript 实现/jquery.But 我更喜欢角​​度的方式来实现这一点。

简而言之,这是我想要做的两件事,

  • 点击标签时将焦点放在输入元素上。
  • 当焦点转移到另一个输入元素并且前一个元素不为空时(如果输入了某些值)。标签应保持其在顶部的位置。

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;
}

【问题讨论】:

  • 在元素上的第一个焦点事件之后,您希望标签成为常量吗?
  • 你为什么不试试Mat-Input
  • 如果输入没有值,标签应该回到原来的位置。但如果它有一些值,它应该是常数,当值被移除并且焦点不在时,它应该回到原来的位置..感谢您的建议,但我试图避免材料..

标签: javascript css angular typescript


【解决方案1】:
  1. 在 html 中,添加对输入文本的引用 - #firstNameField 并添加一个方法来单击标签的事件 - (click)="focusOnFirstName()"
    <input #firstNameField class="input" type="text">
    <label class="label" (click)="focusOnFirstName()">First Name</label>

  1. 在您的组件中声明 ViewChild 并实现单击标签字段的方法。
      @ViewChild("firstNameField") firstNameField;

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


【讨论】:

  • 谢谢它几乎解决了我的问题,除了第二部分..如果有值,标签应该保留在顶部。删除时它应该回到原来的位置
【解决方案2】:

您可以使用纯标记来做到这一点。您需要在输入中添加一个 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>

【讨论】:

  • 谢谢,现在我可以做第一部分了..但是你能解释一下它是如何工作的吗?你也可以帮助我,而输入有一些价值..标签应该保持在顶部跨度>
  • 谢谢它解决了它。如果有一种方法可以在不为每个输入创建单独的变量的情况下动态生成它,你只能建议我
  • [(ngModel)] 是跟踪输入值的完美解决方案。确保导入表单模块,以免出现未知指令错误: import { FormsModule } from '@angular/forms'
【解决方案3】:

我是从为您的条件样式请求制定更“有角度”的解决方案的角度来看待这个问题的。为此,您应该专注于将输入/标签组合滚动到自定义输入组件中。使用原始元素作为起始模板创建组件后,您可以更有效地执行以下操作。

基本策略是使用 Angular 的 [class] 属性绑定或 [NgStyle] 指令有条件地应用您的样式。

  1. 对输入元素的模板执行 ViewChild 查询
    1. 在模板的输入元素上添加事件监听器
    2. 每当检测到 keyup 事件时,都会触发检查您的 &lt;input&gt; 字段值并更新表示该字段是否为空的类属性
    3. 将触发更改检测,并且 [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>

【讨论】:

  • 感谢您的宝贵时间..如果您将其作为指令,我们如何将其附加到表单中..在我的情况下,它是响应式表单..特定的输入指令将要求表单仅在父组件中可用的组..有没有办法克服这个问题?
  • 另外附加的代码看起来有点混乱,你能分享一下stackblitz吗?
猜你喜欢
  • 2015-11-07
  • 2017-06-17
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 2018-06-22
  • 2019-01-15
  • 2013-04-26
  • 1970-01-01
相关资源
最近更新 更多