jQueryの focus() メソッドを使うと、プログラムで特定の入力欄にフォーカスを移動できます。モーダルを開いたときに自動で入力欄を選択したり、バリデーションエラー後に問題のある欄にフォーカスを移したりする実装で重要です。この記事では基本的なfocus()・tabindexの使い方・非表示要素へのフォーカス・フォーカス制御のアクセシビリティまで解説します。
この記事でわかること
- focus() で要素にフォーカスを当てる基本
- tabindex を使って通常はフォーカスできない要素をフォーカス可能にする
- モーダル開閉時のフォーカス管理
- フォーカスイベント(focus / blur / focusin / focusout)の使い分け
- フォーカス関連のアクセシビリティ注意点
focus() の基本的な使い方
$(function () {
// ページ読み込み後に入力欄にフォーカス
$('#name-input').focus();
// ボタンクリックで別の要素にフォーカスを移動
$('#move-btn').on('click', function () {
$('#search-input').focus();
});
// フォーカスと同時にテキストを全選択
$('#amount-input').focus().select();
});
focus() はフォーカス可能な要素にのみ有効
input・textarea・select・button・a などは標準でフォーカス可能です。div・p・span などはデフォルトでフォーカスできないため、tabindex 属性の追加が必要です。tabindex でフォーカス可能にする
<!-- tabindex="0" で標準のタブ順序に追加 --> <div id="custom-select" tabindex="0" role="listbox">カスタム選択肢</div> <!-- tabindex="-1" でJSからはフォーカスできるがタブキーではスキップ --> <div id="modal-dialog" tabindex="-1" role="dialog">モーダル内容</div>
$(function () {
// tabindex='0' の要素: タブキーと focus() 両方でフォーカス可能
$('#custom-select').on('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') {
// Enterやスペースで選択
$(this).toggleClass('selected');
}
});
// tabindex='-1' の要素: JS から focus() でのみフォーカスできる
// → モーダルを開くとき用(タブキーでは到達しない)
$('#open-modal-btn').on('click', function () {
$('#modal-dialog').show().focus();
});
});
モーダル開閉時のフォーカス管理
アクセシビリティを考慮したモーダルでは、開いたときにモーダル内にフォーカスを移動し、閉じたときに元の要素にフォーカスを戻す必要があります。
$(function () {
var $lastFocus; // 元のフォーカス要素を保存
$('#open-modal-btn').on('click', function () {
$lastFocus = $(document.activeElement); // 現在のフォーカスを保存
$('#modal').show();
$('#modal-first-input').focus(); // モーダル内の最初の入力欄にフォーカス
});
$('#close-modal-btn').on('click', function () {
$('#modal').hide();
$lastFocus.focus(); // 元の要素にフォーカスを戻す
});
// フォーカストラップ(モーダル外にフォーカスが出ないようにする)
$('#modal').on('keydown', function (e) {
if (e.key !== 'Tab') return;
var $focusable = $(this).find('input, button, [tabindex="0"]').filter(':visible');
var $first = $focusable.first();
var $last = $focusable.last();
if (e.shiftKey && document.activeElement === $first[0]) {
e.preventDefault();
$last.focus();
} else if (!e.shiftKey && document.activeElement === $last[0]) {
e.preventDefault();
$first.focus();
}
});
});
フォーカスイベントの使い分け
| イベント | バブリング | 説明 |
|---|---|---|
focus |
なし | 要素がフォーカスを得たとき |
blur |
なし | 要素がフォーカスを失ったとき |
focusin |
あり | 要素またはその子孫がフォーカスを得たとき(親でまとめて監視) |
focusout |
あり | 要素またはその子孫がフォーカスを失ったとき |
$(function () {
// 入力欄にフォーカスが当たったらラベルをアクティブに
$('input').on('focus', function () {
$(this).closest('.form-group').addClass('is-focused');
}).on('blur', function () {
$(this).closest('.form-group').removeClass('is-focused');
});
// フォーム全体のフォーカス監視(focusinはバブリングするため親で監視できる)
$('#contact-form').on('focusin', function () {
console.log('フォーム内のいずれかにフォーカス');
}).on('focusout', function () {
console.log('フォームからフォーカスが外れた');
});
});
まとめ
jQueryでフォーカスを制御する際のポイントをまとめます。
- 基本:
$(el).focus()でプログラムからフォーカスを移動 - tabindex=”0″: タブキーでも到達可能にする / “-1”: JSからのみフォーカス可能
- モーダル: 開いたとき最初の要素にフォーカス → 閉じたとき元の要素に戻す
- フォーカスイベント:
focus/blur(バブリングなし)/focusin/focusout(バブリングあり)
関連記事: フォームバリデーション完全ガイド / 画像クリックで拡大表示する完全ガイド
よくある質問(FAQ)
Qfocus()が動かないです。
A主な原因は3つです。①要素がフォーカス不可能(
div等 → tabindex追加)。②要素が非表示(display:none・visibility:hidden の要素はフォーカス不可)。③DOM読み込み前に実行している($(function(){}) 内で実行してください)。Qバリデーションエラー後に最初のエラー欄にフォーカスしたいです。
Aエラーのある入力欄にクラスを付与し、最初の一つにフォーカスします:
$(".is-error").first().focus();さらにスムーズスクロールで画面内に表示させると UX が向上します:$("html,body").animate({ scrollTop: $(".is-error").first().offset().top - 100 })Qフォーカスのアウトラインを消したいです。
A
outline: none でフォーカスリングを消せますが、キーボードユーザーのアクセシビリティが損なわれるため推奨されません。代わりに :focus-visible 疑似クラスを使うと、マウス操作時だけアウトラインを非表示にし、キーボード操作時は表示できます。Qページ読み込み時に自動でフォーカスしたいです。
AHTMLの
autofocus 属性が最も簡単です:<input id="search" autofocus>jQueryで行う場合は $(function() { $("#search").focus(); }); です。ただし、ページ上部にある要素以外に自動フォーカスすると、スクリーンリーダーユーザーが混乱することがあるため注意してください。Qフォーカスが当たっている要素を取得したいです。
A
document.activeElement で現在フォーカスされている要素を取得できます。jQueryで使う場合は $(document.activeElement) です。何にもフォーカスがない場合は document.body が返ります。