【问题标题】:autofocus in html input tag only works once. Is there a way I can focus the input box automatically in another way?html 输入标签中的自动对焦只能工作一次。有没有办法可以以另一种方式自动聚焦输入框?
【发布时间】:2017-06-23 06:12:26
【问题描述】:

我正在开发一个需要快速编辑单个单词的浏览器内编辑器。我试图通过用包含这些单词的输入框替换特定单词然后允许用户当场编辑该单词来实现它。

因为我希望这个过程很快,所以我想确保输入字段在切换后立即获得焦点,并且我当前的解决方案是在输入标签中使用“autofocus”关键字。

这适用于页面加载后的第一次编辑,但不适用于后续编辑。

演示视频:

https://i.gyazo.com/0d1099b2f60b47ff504e3f5bab54fa8f.mp4

我也尝试过使用 DOM 操作来实现这一点,但由于某种原因,它无法找到带有标签的元素,我觉得这是因为它是动态生成的。

相关源码:

HTML 模板

template: `
<div class="content" *ngFor="let sentence of sentences; let s_i = index;">
  <span class="content" *ngFor="let word of sentence; let i = index; trackBy:trackByFn">

    <span *ngIf="(currentIndex === i) && (currentSentence === s_i) && !(editing)"
          class="selectedWord"
          (click)="onClick(s_i, i)">{{word}} </span>
    <input *ngIf="(currentIndex === i) && (currentSentence === s_i) && (editing)"
          id="editingWord"
          (click)="onClick(s_i, i)"
          type="text"
          [(ngModel)]="sentences[s_i][i]"
          autofocus>
    <span *ngIf="(currentIndex !== i) || (currentSentence !== s_i)"
          (click)="onClick(s_i, i)">{{word}} </span>
  </span>
  <br>
</div>

<span class="content" *ngFor="let word of array; let i = index;"> 

</span>
`

我尝试使用 DOM 操作来解决这个问题

按下编辑键时会调用这些方法:

private editWord = function() {
  this.editing = true;
}

private focusWord = function() {
  console.log("Focusing word");
  var item = document.getElementsByClassName(".selectedWord");
  console.log(item);
  setTimeout(() => document.getElementById("#editingWord").focus(), 2000);
}

另外,有没有办法在输入框最初聚焦时突出显示所有字符?这样,用户可以立即开始输入以替换整个框。

【问题讨论】:

    标签: javascript html angular


    【解决方案1】:

    在再次聚焦之前使用document.activeElement.blur()

    【讨论】:

      【解决方案2】:

      这里更角度的方法是使用 ViewChild:

      @ViewChild('myInput', {static: false})
      myInput;
      
      private focusWord = function() {
          this.myInput.nativeElement.select(); // select focuses the input and selects text
      }
      

      这可能会在使用 ngIf 时出现一些计时问题,需要超时等等,因此您可以考虑使用一个类来隐藏它:

      <input [class.hidden]="(currentIndex === i) && (currentSentence === s_i) && (editing)"
            id="editingWord"
            (click)="onClick(s_i, i)"
            type="text"
            [(ngModel)]="sentences[s_i][i]">
      

      使用一些 CSS,例如 .hidden { display: none; }

      最全功能/可重用的解决方案是实现某种自动选择指令:

      import { AfterContentInit, Directive, ElementRef, Input } from '@angular/core';
      
      @Directive({
          selector: '[autoSelect]'
      })
      export class AutoSelectDirective implements AfterContentInit {
      
          public constructor(private el: ElementRef) { } // inject the element ref
      
          public ngAfterContentInit() { // run at the latest hook
              setTimeout(() => {
                  this.el.nativeElement.select(); // run select after a timeout
              }, 500);
          }
      }
      

      您可以根据需要声明/导入它,然后使用很简单:

      <input [class.hidden]="(currentIndex === i) && (currentSentence === s_i) && (editing)"
            id="editingWord"
            (click)="onClick(s_i, i)"
            type="text"
            [(ngModel)]="sentences[s_i][i]"
            autoSelect>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-16
        相关资源
        最近更新 更多