管理焦点
手动对焦管理
¥Manual Focus Management
Ionic 在 输入、搜索栏 和 文本区 等组件上提供了 setFocus
API,允许开发者手动将焦点设置到元素。该 API 应该用来代替 autofocus
属性并在以下位置调用:
¥Ionic provides a setFocus
API on components such as Input, Searchbar, and Textarea that allows developers to manually set focus to an element. This API should be used in place of the autofocus
attribute and called within:
-
进入页面时路由应用的
ionViewDidEnter
生命周期事件。¥The
ionViewDidEnter
lifecycle event for routing applications when a page is entered. -
渲染叠加层时叠加层的
didPresent
生命周期事件。¥The
didPresent
lifecycle event for overlays when an overlay is presented. -
应用加载时,普通 JavaScript 应用的
appload
事件。¥The
appload
event for vanilla JavaScript applications when the application loads. -
用户手势或交互的结果。
¥The result of a user gesture or interaction.
为什么不自动对焦?
¥Why not autofocus?
autofocus
属性是一个标准 HTML 属性,允许开发者在页面加载时将焦点设置到某个元素。此属性通常用于将焦点设置到页面上的第一个输入元素。但是,在页面之间导航时,autofocus
属性可能会导致路由应用出现问题。这是因为 autofocus
属性会在页面加载时将焦点设置到元素,但在重新访问页面时不会将焦点设置到元素。了解有关 MDN 网络文档 中 autofocus
属性的更多信息。
¥The autofocus
attribute is a standard HTML attribute that allows developers to set focus to an element when a page loads. This attribute is commonly used to set focus to the first input element on a page. However, the autofocus
attribute can cause issues in routing applications when navigating between pages. This is because the autofocus
attribute will set focus to the element when the page loads, but will not set focus to the element when the page is revisited. Learn more about the autofocus
attribute in the MDN Web Docs.
平台限制
¥Platform Restrictions
使用 setFocus
API 时你应该注意一些平台限制,包括:
¥There are platform restrictions you should be aware of when using the setFocus
API, including:
-
Android 在将焦点设置到元素之前需要用户交互。这就像用户点击屏幕一样简单。
¥Android requires user interaction before setting focus to an element. This can be as simple as a user tapping on the screen.
-
交互元素只能聚焦 Mobile Safari (iOS) 上用户手势的结果,例如作为按钮单击的结果调用
setFocus
。¥Interactive elements can only focused a result of a user gesture on Mobile Safari (iOS), such as calling
setFocus
as the result of a button click.
基本用法
¥Basic Usage
下面的示例演示了如何使用 setFocus
API 在用户单击按钮时请求焦点位于输入上。
¥The example below demonstrates how to use the setFocus
API to request focus on an input when the user clicks a button.
路由
¥Routing
开发者可以使用 ionViewDidEnter
生命周期事件在进入页面时将焦点设置到某个元素。
¥Developers can use the ionViewDidEnter
lifecycle event to set focus to an element when a page is entered.
- 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 is currently required due to:
// https://github.com/ionic-team/ionic-framework/issues/24434
input.value.$el.setFocus();
});
});
</script>
叠加层
¥Overlays
当渲染叠加层时,开发者可以使用 didPresent
生命周期事件将焦点设置到元素。
¥Developers can use the didPresent
lifecycle event to set focus to an element when an overlay is presented.
- 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>
辅助技术焦点管理
¥Assistive Technology Focus Management
默认情况下,单页应用没有内置方法来通知屏幕阅读器浏览器或 Web 视图中的活动视图已更改。这意味着依赖辅助技术的用户并不总是知道导航事件是否发生。
¥By default, Single Page Applications have no built-in way of informing screen readers that the active view has changed in a browser or webview. This means that users who rely on assistive technology do not always know if a navigation event occurred.
启用 focusManager 优先级配置 的开发者可以在页面转换期间将焦点管理委托给 Ionic。启用后,Ionic 会将焦点移动到配置选项中指定的正确元素。这将通知屏幕阅读器发生了导航事件。
¥Developers who enable the focusManagerPriority config can delegate focus management to Ionic during page transitions. When enabled, Ionic will move focus to the correct element as specified in the config option. This will inform screen readers that a navigation event occurred.
类型
¥Types
type FocusManagerPriority = 'content' | 'heading' | 'banner';
内容类型
¥Content Types
下表解释了每种内容类型代表的含义:
¥The following table explains what each content type represents:
类型 | 描述 | Ionic 组件 | 语义 HTML 等效项 | 同等地标 |
---|---|---|---|---|
content | 视图的主要部分。 | 内容 | main | role="main" |
heading | 视图的标题。 | 标题 | h1 | role="heading" 与 aria-level="1" |
banner | 视图的标题。 | 标头 | header | role="banner" |
开发者应将 role="heading"
和 aria-level="1"
分配给每个视图上的主 标题。由于可以在单个视图中使用多个 标题 组件,Ionic 不会自动分配这些属性。
¥Developers should assign role="heading"
and aria-level="1"
to the primary Title on each view. Since multiple Title components can be used in a single view, Ionic does not automatically assign these attributes.
指定优先级
¥Specifying Priority
应按优先级降序指定配置。在下面的示例中,Ionic 将始终聚焦标题来开始。如果视图没有标题,Ionic 仅前进到下一个焦点优先级,横幅:
¥The config should be specified in order of decreasing priority. In the following example, Ionic will always focus headings to start. Ionic only proceeds to the next focus priority, banner, if a view does not have a heading:
focusManagerPriority: ['heading', 'banner'];
实现说明
¥Implementation Notes
-
当指定焦点优先级时,浏览器仍然可以在该焦点优先级内移动焦点。例如,当指定
'content'
焦点优先级时,Ionic 会将焦点移动到内容。然而,浏览器随后可以将该内容内的焦点移动到诸如按钮之类的第一可聚焦元素。¥When specifying a focus priority, browsers may still move focus within that focus priority. For example, when specifying a
'content'
focus priority, Ionic will move focus to the content. However, the browser may then move focus within that content to the first focusable element such as a button. -
如果在视图中找不到任何焦点优先级,Ionic 将会聚焦视图本身,以确保焦点通常移动到正确的位置。然后浏览器可以调整视图内的焦点。
¥If none of the focus priorities are found in a view, Ionic will instead focus the view itself to ensure focus generally moves to the correct place. Browsers may then adjust focus within the view.
-
从当前视图导航到上一个视图时,Ionic 会将焦点移回到渲染当前视图的元素。
¥When navigating from the current view to the previous view, Ionic will move focus back to the element that presented the current view.
-
可以按视图覆盖焦点管理器,如 带路由的手动焦点管理 中所示。
¥The focus manager can be overridden on a per-view basis as shown in Manual Focus Management with Routing.