Managing Focus
手動フォーカス管理
Ionic は、Input、Searchbar、TextareaなどのコンポーネントにsetFocus API を提供し、開発者が要素に手動でフォーカスを設定できるようにします。この API はautofocus属性の代わりに使用し、以下のタイミングで呼び出す必要があります:
- ルーティングアプリケーションでページが入力されたときの
ionViewDidEnterライフサイクルイベント。 - オーバーレイが表示されたときのオーバーレイの
didPresentライフサイクルイベント。 - アプリケーションが読み込まれたときのバニラ JavaScript アプリケーションの
apploadイベント。 - ユーザーのジェスチャーやインタラクションの結果。
なぜ autofocus を使わないのか?
autofocus属性は、ページが読み込まれたときに要素にフォーカスを設定できる標準の HTML 属性です。この属性は、通常、ページの最初の入力要素にフォーカスを設定するために使用されます。ただし、autofocus属性は、ページ間をナビゲートする際にルーティングアプリケーションで問題を引き起こす可能性があります。これは、autofocus属性がページが読み込まれたときに要素にフォーカスを設定しますが、ページが再訪問されたときに要素にフォーカスを設定しないためです。autofocus属性の詳細については、MDN Web Docsを参照してください。
プラットフォームの制限
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 is currently required due to:
// 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';
コンテンツタイプ
次の表は、各コンテンツタイプが何を表すかを説明しています:
| Type | 説明 | Ionic Component | Semantic HTML Equivalent | Landmark Equivalent |
|---|---|---|---|---|
content | ビューの主要部分。 | Content | main | role="main" |
heading | ビューのタイトル。 | Title | h1 | role="heading" with aria-level="1" |
banner | ビューのヘッダー。 | Header | header | role="banner" |
優先順位の指定
設定は優先順位の降順で指定する必要があります。次の例では、Ionic は常に最初に見出しにフォーカスします。ビューに見出しがない場合にのみ、Ionic は次のフォーカス優先順位である banner に進みます:
focusManagerPriority: ['heading', 'banner'];
実装に関する注意事項
- フォーカス優先順位を指定する場合、ブラウザはそのフォーカス優先順位内でフォーカスを移動する場合があります。たとえば、
'content'フォーカス優先順位を指定すると、Ionic はコンテンツにフォーカスを移動します。ただし、ブラウザはその後、そのコンテンツ内の最初のフォーカス可能な要素(ボタンなど)にフォーカスを移動する場合があります。 - ビューでフォーカス優先順位が見つからない場合、Ionic は代わりにビュー自体にフォーカスを移動して、フォーカスが一般的に正しい場所に移動するようにします。その後、ブラウザはビュー内でフォーカスを調整する場合があります。
- 現在のビューから前のビューにナビゲートする場合、Ionic は現在のビューを表示した要素にフォーカスを戻します。
- フォーカスマネージャーは、ルーティングでの手動フォーカス管理に示すように、ビューごとにオーバーライドできます。