【问题标题】:How to trigger keyup function after certain number of strokes如何在一定数量的笔划后触发keyup功能
【发布时间】:2021-12-01 04:49:01
【问题描述】:

我制作了一个简单的表格,我应该输入一个电话号码,分为三个部分,第一个输入需要 3,第二个输入需要 3,最后一个应该需要 4。我为输入元素设置了 maxlength,我正在打电话keyup 专注于下一个元素。但是在我输入一个数字后,它会跳转到下一个输入,而不是 3 笔。

这是我的codesandbox 供你玩耍

这是我的 HTML

<div class="form-group" style="height:70px;">
  <label class="reg_txt">Phone Number  <span>*</span></label>
  <div class="clearfix"></div>
  <div class="wsite-form">
    <input type="text" class="text input-name1" formControlName="phone1" maxlength="3" (keyup)="nextStep($event,1)" (focus)="focused(1)" id="code1">
  </div>
  <div class="line">-</div>
  <div class="wsite-form">
    <input type="text" class="text input-name1" formControlName="phone2" maxlength="3" (keyup)="nextStep($event,2)" (focus)="focused(2)" id="code2">
  </div>
  <div class="line">-</div>
  <div class="wsite-form">
    <input type="text" class="text input-name1" formControlName="phone3" maxlength="4" (keyup)="nextStep($event,3)" (focus)="focused(3)" id="code3">
  </div>

</div>

这是我的组件方法

nextStep(event, step: number): void {
  const prevElement = document.getElementById('code' + (step - 1));
  const nextElement = document.getElementById('code' + (step + 1));
  console.log(event)
  if (event.code == 'Backspace' && event.target.value === '') {
    event.target.parentElement.parentElement.children[step - 2 > 0 ? step - 2 : 0].children[0].value = ''
    if (prevElement) {
      prevElement.focus()
      return
    }
  } else {
    if (nextElement) {
      nextElement.focus()
      return
    } else {

    }
  }
}

如果我按退格键,它应该跳转到前一个元素,它适用于第二个输入框,它会为最后一个元素抛出错误。我知道我犯了一个愚蠢的错误,谁能指出我正确的方向。如有任何帮助,我将不胜感激。

【问题讨论】:

  • 在每个 keyup 事件中,您都可以检查输入的长度,如果它超过最大长度,那么您可以选择下一个输入,也可以选择上一个输入选择!!
  • 我会试试然后回复你
  • @GaurangDhorda 可悲的是不起作用\
  • @GaurangDhorda 提出的解决方案如何对您“不起作用”?与计算任意击键(可能是箭头或删除击键)相比,肯定验证输入是否完整且正确填写是一种更稳健的方法......
  • @GaurangDhorda 它有效,我尝试转换为字符串,这是错误的想法。

标签: javascript angular typescript angular-forms


【解决方案1】:

你也可以像这样创建指令(*)

@Directive({
  selector: 'input[maxlength]',
  exportAs: 'child'
})
export class MaxLengthDirective {
  @Input()prev:HTMLElement;
  @Input()next:HTMLElement;

  @HostListener('keyup',['$event']) _(event:any){
     if (!event.target.value && this.prev && event.key=='Backspace')
       this.prev.focus()
     if (event.target.value.length==this.maxLength && this.next)
      this.next.focus()
  }
  constructor(@Attribute('maxlength') private maxLength:number){}
}

你可以用like

<input #one maxlength="3" [next]="two">
<input #two [prev]="one" [next]="three" maxlength="4">
<input #three [prev]="two" maxlength="5">

stackbliz

(*)不要忘记包含在你的模块声明中

更新是的,我也觉得使用模板引用变量和[prev][next]有点复杂,为什么不改进呢?

为此,我们使用两个指令

@Directive({
  selector: 'input[maxlength]',
  exportAs: 'child'
})
export class MaxLengthDirective {

  @HostListener('keyup',['$event']) _(event:any){
     if (!event.target.value && event.key=='Backspace')
       this.parent.prev(this)
     if (event.target.value.length==this.maxLength)
      this.parent.next(this)
  }
  constructor(@Attribute('maxlength') private maxLength:number,@Optional() @Host() private parent:MaxLengthGroupDirective,public elementRef:ElementRef){
  }
}

@Directive({
  selector: '[maxLengthGroup]',
  exportAs: 'maxLengthGroup'
})
export class MaxLengthGroupDirective {
  @ContentChildren(MaxLengthDirective) items:QueryList<MaxLengthDirective>
  next(item:MaxLengthDirective)
  {

     const index=this.items.toArray().findIndex(x=>x==item);
     if (index<this.items.length-1)
     {
       const nextItem=this.items.find((_,i)=>i>index)
       nextItem.elementRef.nativeElement.focus()
     }
  }
  prev(item:MaxLengthDirective)
  {
    const index=this.items.toArray().findIndex(x=>x==item);
    if (index>0)
    {
      const prevItem=this.items.find((_,i)=>i==index-1)
      prevItem.elementRef.nativeElement.focus()
    }
  }
}

max-length-group 使用 ContentChildren 获取最大长度。所以我们在 QueryList 中有所有具有 matlength 的输入。 "next" 和 "prev" 中的两个函数分别关注上一个或下一个元素。为此,我们需要使用 @Host 在 mat-length 中注入 max-length-group,以指示 Angular 搜索该指令。用途是这样的

<div max-length-group>
  <input maxlength="3" placeholder="max 3" />
  <input placeholder="max 4" maxlength="4" />
  <input placeholder="max 5" maxlength="5" />
</div>

new stackblitz

【讨论】:

  • 哇,这看起来很整洁。我试试这个
【解决方案2】:

将此if (nextElement &amp;&amp; event.target.value.length === 3) 添加到nextStep() 底部的else 语句中,而不仅仅是if (nextElement)

如果有下一个元素可以去并且当前输入的长度是3,关注下一个元素。

【讨论】:

  • 我尝试将目标值转换为字符串并比较长度,我应该试试这个。这行得通,谢谢。但是还有一个问题,如果您在第三个时按退格键,它会引发错误,您知道为什么。但它适用于第二个盒子
  • 它试图获取未定义元素的值。你能解释一下你想用这条线实现什么event.target.parentElement.parentElement.children[step - 2 &gt; 0 ? step - 2 : 0].children[0].value = ''
  • 我正在从视图中传递步骤并检查兄弟元素的值
  • 删除该行对我有用。谢谢:)
猜你喜欢
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多