管理焦点
手动焦点管理
Ionic 在 Input、Searchbar 和 Textarea 等组件上提供了 setFocus API,允许开发者手动将焦点设置到某个元素。应使用此 API 代替 autofocus 属性,并在以下时机调用:
- 路由应用中,在页面进入时的
ionViewDidEnter生命周期事件中。 - 覆盖层中,在覆盖层展示时的
didPresent生命周期事件中。 - 纯 JavaScript 应用中,在应用加载时的
appload事件中。 - 用户手势或交互的结果中。
为什么不用 autofocus?
autofocus 属性是一个标准的 HTML 属性,允许开发者在页面加载时将焦点设置到某个元素。此属性通常用于将焦点设置到页面的第一个输入元素。然而,在路由应用中,autofocus 属性在页面之间导航时可能会导致问题。这是因为 autofocus 属性会在页面加载时设置焦点,但在重新访问页面时不会设置焦点。在 MDN Web 文档 中了解更多关于 autofocus 属性的信息。
平台限制
在使用 setFocus API 时,您应该了解以下平台限制:
- Android 要求在与元素进行用户交互后才能设置焦点。这可以简单到用户点击屏幕即可。
- 在 Mobile Safari(iOS)上,交互式元素只能作为用户手势的结果来聚焦,例如在按钮点击时调用
setFocus。
基本用法
以下示例演示了如何使用 setFocus API 在用户点击按钮时请求将焦点设置到输入框。
路由
开发者可以使用 ionViewDidEnter 生命周期事件在页面进入时将焦点设置到某个元素。
- Angular
- React
- Vue
/* example.component.ts */
import { Component, ViewChild } from '@angular/core';
import { IonInput } from '@ionic/angular';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
@ViewChild('input') input!: IonInput;
ionViewDidEnter() {
this.input.setFocus();
}
}
import React, { useRef } from 'react';
import { IonInput, IonPage, useIonViewDidEnter } from '@ionic/react';
const Home = () => {
const input = useRef<HTMLIonInputElement>(null);
useIonViewDidEnter(() => {
input.current?.setFocus();
});
return (
<IonPage>
<IonInput ref={input} label="setFocus" labelPlacement="floating"></IonInput>
</IonPage>
);
};
export default Home;
<template>
<ion-page>
<ion-input ref="input" label="setFocus" label-placement="floating"></ion-input>
</ion-page>
</template>
<script setup lang="ts">
import { IonInput, IonPage, onIonViewDidEnter } from '@ionic/vue';
import { ref } from 'vue';
const input = ref();
onIonViewDidEnter(() => {
requestAnimationFrame(() => {
// 当前需要 requestAnimationFrame,原因:
// https://github.com/ionic-team/ionic-framework/issues/24434
input.value.$el.setFocus();
});
});
</script>
覆盖层
开发者可以使用 didPresent 生命周期事件在覆盖层展示时将焦点设置到某个元素。
- JavaScript
- Angular
- React
- Vue
<ion-modal>
<ion-input></ion-input>
</ion-modal>
<script>
const modal = document.querySelector('ion-modal');
modal.addEventListener('didPresent', () => {
const input = modal.querySelector('ion-input');
input.setFocus();
});
</script>
/* example.component.ts */
import { Component, ViewChild } from '@angular/core';
import { IonInput } from '@ionic/angular';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
@ViewChild('input') input!: IonInput;
onDidPresent() {
this.input.setFocus();
}
}
<!-- example.component.html -->
<ion-modal (didPresent)="onDidPresent()">
<ion-input #input></ion-input>
</ion-modal>
import React, { useRef } from 'react';
import { IonInput, IonModal } from '@ionic/react';
const Home = () => {
const input = useRef<HTMLIonInputElement>(null);
const onDidPresent = () => {
input.current?.setFocus();
};
return (
<IonModal onDidPresent={onDidPresent}>
<IonInput ref={input}></IonInput>
</IonModal>
);
};
export default Home;
<template>
<ion-modal @didPresent="onDidPresent">
<ion-input ref="input"></ion-input>
</ion-modal>
</template>
<script setup lang="ts">
import { IonInput, IonModal } from '@ionic/vue';
import { ref } from 'vue';
const input = ref();
function onDidPresent() {
input.value.$el.setFocus();
}
</script>
辅助技术焦点管理
默认情况下,单页应用没有内置的方式通知屏幕阅读器当前视图已在浏览器或 webview 中发生变化。这意味着依赖辅助技术的用户并不总是知道导航事件是否发生。
启用 focusManagerPriority 配置 的开发者可以在页面过渡期间将焦点管理委托给 Ionic。启用后,Ionic 将根据配置选项中指定的内容将焦点移动到正确的元素。这将通知屏幕阅读器发生了导航事件。
类型
type FocusManagerPriority = 'content' | 'heading' | 'banner';
内容类型
下表解释了每种内容类型的含义:
| 类型 | 描述 | Ionic 组件 | 语义 HTML 等效 | 地标等效 |
|---|---|---|---|---|
content | 视图的主要内容部分。 | Content | main | role="main" |
heading | 视图的标题。 | Title | h1 | role="heading" 配合 aria-level="1" |
banner | 视图的页眉。 | Header | header | role="banner" |
important
指定优先级
配置应按优先级递减的顺序指定。在以下示例中,Ionic 将始终首先聚焦标题。仅当视图没有标题时,Ionic 才会继续下一个焦点优先级,即 banner:
focusManagerPriority: ['heading', 'banner'];
实现说明
- 在指定焦点优先级时,浏览器可能仍会在该焦点优先级内移动焦点。例如,当 指定
'content'焦点优先级时,Ionic 会将焦点移动到内容区域。但是,浏览器随后可能会将焦点移动到该内容区域内的第一个可聚焦元素,例如按钮。 - 如果在视图中未找到任何焦点优先级,Ionic 将改为聚焦视图本身,以确保焦点大致移动到正确的位置。浏览器随后可能会在视图中调整焦点。
- 当从当前视图导航到上一个视图时,Ionic 会将焦点移回到展示当前视图的元素上。
- 焦点管理器可以按每个视图进行覆盖,如使用路由的手动焦点管理所示。