在Ionic 2中将焦点设置到输入框

47

已解决:

import { Component, ViewChild} from '@angular/core';
import { Keyboard } from 'ionic-native';


@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('input') myInput ;

  constructor() {}

  ionViewDidLoad() {

    setTimeout(() => {
      Keyboard.show() // for android
      this.myInput.setFocus();
    },150);

 }

} 

1) 导入 "ViewChild"

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

2) 在HTML模板中创建对输入的引用:

<ion-input #focusInput></ion-input>

3) 使用 @ViewChild 获取之前引用的输入组件。

@ViewChild('focusInput') myInput;

4) 触发焦点

使用 ionViewLoaded() 方法,在每次加载视图/页面时触发它。

需要 setTimeout

  ionViewLoaded() {

    setTimeout(() => {
      Keyboard.show() // for android
      this.myInput.setFocus();
    },150); //a least 150ms.

 }

4) 在Android上显示键盘

import { Keyboard } from 'ionic-native';

调用Keyboard.show()在Android上呼出键盘。

5) 在iOS上显示键盘

将以下行添加到您的config.xml中以使其在iOS上工作:

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

借助于mhartington的优秀文章:http://mhartington.io/post/setting-input-focus/


1
它在iOS上不起作用 :( - Ciprian Mocanu
2
ionViewLoaded() did not work for me, I had to use ionViewDidLoad() - JCisar
当我进行这个操作时,构建过程中出现了"ngc: 错误: 无法对引用或变量进行赋值!"的错误提示。 - Quintin Balsdon
@QuintinBalsdon 当您将与ts类中已有的属性相同的引用(ref)赋给它时,就会发生这种情况。请考虑更改引用名称,例如"#somethingElse"。 - Toby Okeke
3
你能使用“发布你的答案”按钮将问题转换为新的回答吗?把答案放在问题正文中会让人感到困惑,当我找到你的问题时,我无法理解哪里是答案。发表一个新的答案,并将其标记为正确的答案,这将有助于人们更好地指导自己 :) - Guilherme Nascimento
显示剩余2条评论
10个回答

14

您无需从'angular/core'中导入'Input'。

只需:

import {Component,ViewChild} from '@angular/core';
import {NavController, TextInput } from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('input') myInput: TextInput;

  constructor(private navCtrl: NavController) { }

  ionViewDidLoad() {

    setTimeout(() => {
      this.myInput.setFocus();
    },150);

 }

} 

回复Ciprian Mocanu的评论:

这在iOS上不起作用 :(

它在iOS上可以使用 - 在安装有iOS 10的iPhone 6 PLUS上进行了检查


2
实际上,如果你在iOS上使用的是WKWebView,它是不会起作用的,就像这个Cordova问题描述的那样:https://issues.apache.org/jira/browse/CB-10376。提供的修复方案在UIWebView上是有效的。 - jean-baptiste
这个在 iPhone 6S 上使用 WKWebView 和 ionic-angular 3.9.2,在 iOS 11.3.1 上可以正常工作。 - Alex Steinberg

7

我认为你应该为此制定一个全局指令,因为您可能会多次需要这种行为。

import {  ViewChild, ElementRef, Directive, OnInit } from '@angular/core';
import { Keyboard } from 'ionic-native';

@Directive({
    selector: '[autofocus]'
})
export class FocusInput implements OnInit {
    @ViewChild('myinput') input
    private focused: boolean
    ngOnInit(){
      this.focused = true
    }
    ionViewDidLoad() {
      if (this.focused) {
        setTimeout(()=>{
          this.input.setFocus()
          this.focused = false
          Keyboard.show()
        }, 300)
      }
    }
}

现在,在你的ion-input字段中只需添加autofocus属性。
<ion-input #myinput type="..." placeholder="..."
            (keyup.enter)="someAction()"
            autofocus ></ion-input>

1
ionViewDidLoad没有触发。这是一个ion-input控件的正确事件吗? - Tony O'Hagan
指令下既不支持 ionViewDidLoad 也不支持 ViewChild. - nishil bhave

6

上述方法对我来说都不起作用。以下是我是如何解决的:

import {  ElementRef, AfterViewChecked, Directive } from '@angular/core';
import {Keyboard} from 'ionic-native';

@Directive({
    selector: '[autofocus]'
})
export class FocusInput implements AfterViewChecked {
    private firstTime: boolean = true;
    constructor(public elem: ElementRef) {
}

ngAfterViewChecked() {
  if (this.firstTime) {
    let vm = this;
    setTimeout(function(){

    vm.elem.nativeElement.firstChild.focus();
    vm.firstTime = false;
    Keyboard.show();

    }, 300)
  }
 }
}

然后在您的ion-input字段中添加autofocus属性:

 <ion-input #input type="text" placeholder="..."
            [(ngModel)]="myBoundVariable"
            (keyup.enter)="myEnterKeyAction()"
            autofocus></ion-input>

已在浏览器和安卓设备上进行了测试,尚未在IOS上测试,但没有理由不可行。


5

import {Component, ViewChild} from '@angular/core';
import {NavController} from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('Comment') myInput ;

  constructor(private navCtrl: NavController) { }

  ionViewLoaded() {

    setTimeout(() => {
      this.myInput.setFocus();
    },150);

 }

}

Create a reference to your input in your template :

<ion-input #Comment>


为什么是150毫秒? - Khurshid Ansari

3
import {Component,ViewChild} from '@angular/core';
import {NavController} from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('myInput') myInput ;

  constructor(private navCtrl: NavController) { }

  ionViewDidLoad() {

    window.setTimeout(() => {
      this.myInput.setFocus();
    }, 600); //SET A LONG TIME IF YOU ARE IN A MODAL/ALERT

  }

}

<ion-input #myInput ></ion-input>

2
如果您需要在初始化组件时将焦点设置在输入框上,请将class input-has-focus默认设置为ion-item,就像这样:
<ion-item class="input-has-focus">

这就是全部内容了!


1
我发现这个解决方案也可以解决键盘推动内容的问题。
<ion-list>
<ion-item>
  <ion-label>Name</ion-label>
  <ion-input #inputRef type="text"></ion-input>
</ion-item>
<button ion-button (click)="focusMyInput(inputRef)">Focus</button>

  @ViewChild(Content) content: Content;

  focusMyInput(inputRef) {
    const itemTop = inputRef._elementRef.nativeElement.getBoundingClientRect().top;
    const itemPositionY = this.content.scrollTop + itemTop -80;

    this.content.scrollTo(null, itemPositionY, 500, () => {
      inputRef.setFocus();
    });
  }

0

对于IOS和Android,它对我来说工作得很好。将焦点代码放在ionViewWillEnter()中。

import { Component, ViewChild, ElementRef } from '@angular/core';
 import { Keyboard } from '@ionic-native/keyboard';
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 @ViewChild("Input") inputEl: ElementRef;
 constructor(public keyboard:Keyboard){}

 ionViewWillEnter() { 
    setTimeout(() => {           
      this.inputEl.nativeElement.focus();
      this.keyboard.show();    
    }, 800); //If its your first page then larger time required 
}

HTML文件中的输入标签

 <ion-input type="text" #Input></ion-input>

并将以下行添加到您的config.xml文件中,以使其在iOS上正常工作:

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

0
在我的情况下,由于某种原因,ionViewLoaded() 没有被触发。尝试使用 ionViewDidLoad() 并将计时器设置为 200,这样就可以解决问题了。
对我来说,150 太早了。完整的解决方案:
import { Component, ViewChild } from '@angular/core';//No need to import Input

export class HomePage {

  @ViewChild('inputToFocus') inputToFocus;
  constructor(public navCtrl: NavController) {}

  ionViewDidLoad()
  {
    setTimeout(() => {
      this.inputToFocus.setFocus();
    },200)
  }  
}

在输入标签上:

<ion-input type="text" #inputToFocus></ion-input>

-1

设置超时时间对我很有效!

setTimeout(() => {
    this.inputToFocus.setFocus();
}, 800); 

然而,如果添加了新的输入元素,则仅将焦点设置为第一个输入元素。


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