島根県安来市のフリーランスエンジニア_プログラマー画像1
【JavaScript】alert()後のfocus()が動かない原因と解決法 | setTimeout活用術 – Eatransform

【JavaScript】alert()後のfocus()が動かない原因と解決法 | setTimeout活用術

JavaScriptの罠:alert()後のfocus()が動かない問題と解決法

setTimeout()を使った確実な対処方法

よくある困った状況

入力チェックでエラーを見つけた時、alert()を出して、その後に入力欄にfocus()で戻したい…でも動かない!

動かないコード

BAD
function validateInput() {
  const input = document.getElementById('username');
  
  if (!input.value.trim()) {
    alert('ユーザー名を入力してください');
    input.focus(); // ← 動かない!
  }
}

なぜ動かないのか

原因:フォーカス処理の競合

  1. alert()を閉じる動作が非同期で実行される
  2. alert()のウィンドウからフォーカスを外す処理が走る
  3. input.focus()の処理も同時に走る
  4. 結果:フォーカスが当たった瞬間に外される

ブラウザごとに挙動が違う

  • Firefox: フォーカスが移動しない程度
  • Chrome: 無限にalert()が発動し続ける

解決策:setTimeout()で非同期化

ポイント:フォーカス処理を1ミリ秒ずらす

alert()を閉じる処理が完全に終わった後にfocus()を実行すれば、競合しません。

GOOD
function validateInput() {
  const input = document.getElementById('username');
  
  if (!input.value.trim()) {
    alert('ユーザー名を入力してください');
    
    // setTimeout で非同期化!
    setTimeout(function() {
      input.focus();  // フォーカスを戻す
      input.select();  // 全選択
    }, 1); // 1ミリ秒の遅延
  }
}

モダンな書き方(アロー関数)

function validateInput() {
  const input = document.getElementById('username');
  
  if (!input.value.trim()) {
    alert('ユーザー名を入力してください');
    
    // アロー関数でスッキリ
    setTimeout(() => {
      input.focus();
      input.select();
    }, 1);
  }
}

実践例:複数の入力欄がある場合

function validateForm() {
  const username = document.getElementById('username');
  const email = document.getElementById('email');
  
  // ユーザー名チェック
  if (!username.value.trim()) {
    alert('ユーザー名を入力してください');
    setTimeout(() => {
      username.focus();
      username.select();
    }, 1);
    return false;
  }
  
  // メールアドレスチェック
  if (!email.value.trim()) {
    alert('メールアドレスを入力してください');
    setTimeout(() => {
      email.focus();
      email.select();
    }, 1);
    return false;
  }
  
  return true;
}

おまけ:alert()を使わない方法

モダンなWebアプリでは、alert()よりもユーザーフレンドリーな方法があります:

  • HTML5のrequired属性を使う(最もシンプル)
  • インラインエラーメッセージを表示
  • トースト通知やモーダルダイアログを使う
// HTML5のrequired属性を使う例
<input type="text" id="username" required>

// インラインエラーメッセージの例
function validateInput() {
  const input = document.getElementById('username');
  const errorMsg = document.getElementById('error');
  
  if (!input.value.trim()) {
    errorMsg.textContent = 'ユーザー名を入力してください';
    errorMsg.style.display = 'block';
    input.focus(); // alert()がないので普通に動く!
    return false;
  }
}

まとめ

  • alert()の後にfocus()を使う場合は、必ずsetTimeout()で1ミリ秒遅延させる
  • ブラウザによって挙動が異なるため、この対策は必須
  • 可能であれば、alert()よりもモダンなUI手法を検討する

Nginxで/index.htmlを/にリダイレクトする方法【無限ループ解決】

Etransform – 無料WordPressテーマ【シンプル&モダン】ダウンロード