フォーカスの管理
手動フォーカス管理
Ionic は、入力、検索バー、テキストエリアなどのコンポーネントに、開発者が要素に手動でフォーカスを設定できる `setFocus` API を提供しています。この API は `autofocus` 属性の代わりに使用し、以下の場合に呼び出す必要があります。
- ルーティングアプリケーションでページが入力されたときの `ionViewDidEnter` ライフサイクルイベント。
- オーバーレイが表示されたときのオーバーレイの `didPresent` ライフサイクルイベント。
- アプリケーションの読み込み時の Vanilla JavaScript アプリケーションの `appload` イベント。
- ユーザーのジェスチャまたはインタラクションの結果。
なぜ autofocus を使用しないのですか?
`autofocus` 属性は、ページの読み込み時に要素にフォーカスを設定できる標準の HTML 属性です。この属性は、一般的にページの最初の入力要素にフォーカスを設定するために使用されます。ただし、`autofocus` 属性は、ページ間を移動するルーティングアプリケーションで問題を引き起こす可能性があります。これは、`autofocus` 属性はページの読み込み時に要素にフォーカスを設定しますが、ページが再訪されたときには要素にフォーカスを設定しないためです。 `autofocus` 属性の詳細については、MDN Web ドキュメントを参照してください。
プラットフォームの制限
`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>
支援技術フォーカス管理
デフォルトでは、シングルページアプリケーションには、ブラウザまたは Web ビューでアクティブなビューが変更されたことをスクリーンリーダーに通知する組み込みの方法がありません。これは、支援技術に依存しているユーザーは、ナビゲーションイベントが発生したかどうかを常に認識しているわけではないことを意味します。
focusManagerPriority 設定を有効にした開発者は、ページ遷移中にフォーカス管理を Ionic に委任できます。有効にすると、Ionic は設定オプションで指定された正しい要素にフォーカスを移動します。これにより、ナビゲーションイベントが発生したことがスクリーンリーダーに通知されます。
種類
type FocusManagerPriority = 'content' | 'heading' | 'banner';
コンテンツの種類
次の表は、各コンテンツの種類が何を表しているかを説明しています。
種類 | 説明 | Ionic コンポーネント | セマンティック HTML に相当 | ランドマークに相当 |
---|---|---|---|---|
content | ビューの主要部分。 | コンテンツ | main | role="main" |
heading | ビューのタイトル。 | タイトル | h1 | `role="heading"` と `aria-level="1"` |
banner | ビューのヘッダー。 | ヘッダー | header | role="banner" |
優先順位の指定
設定は、優先順位の高い順に指定する必要があります。次の例では、Ionic は常に最初にヘッディングにフォーカスします。ビューにヘッディングがない場合、Ionic は次のフォーカスの優先順位であるバナーに進みます。
focusManagerPriority: ['heading', 'banner'];
実装に関する注意事項
- フォーカスの優先順位を指定した場合でも、ブラウザはそのフォーカスの優先順位内でフォーカスを移動させることがあります。たとえば、`'content'` フォーカスの優先順位を指定した場合、Ionic はコンテンツにフォーカスを移動します。ただし、ブラウザはその後、そのコンテンツ内でボタンなどの最初のフォーカス可能な要素にフォーカスを移動させることがあります。
- ビューにフォーカスの優先順位が見つからない場合、Ionic は代わりにビュー自体にフォーカスを当て、フォーカスが一般的に正しい場所に移動するようにします。ブラウザはその後、ビュー内でフォーカスを調整することがあります。
- 現在のビューから前のビューに移動する場合、Ionic はフォーカスを現在のビューを表示した要素に戻します。
- フォーカスマネージャーは、ルーティングによる手動フォーカス管理に示すように、ビューごとにオーバーライドできます。