12.

JavaScript 確認ダイアログ完全ガイド (confirm / alert / prompt / dialog)

編集
この記事の要点
  • alert("メッセージ") = 通知ダイアログ (OK のみ)
  • confirm("よろしいですか?") = OK / Cancel の 2 択、戻り値 true / false
  • prompt("入力してください", "初期値") = 入力ダイアログ、戻り値 string or null
  • これらは UI を完全ブロックするため現代の SPA では非推奨 → カスタムモーダル推奨
  • 推奨代替: HTML <dialog> 要素 (ネイティブ) / SweetAlert2 / Bootstrap Modal

3 つのネイティブダイアログ

// 1. alert: 通知 (OK ボタンのみ)
alert('保存しました');
// 戻り値: undefined

// 2. confirm: 確認 (OK / Cancel)
const ok = confirm('削除してよろしいですか?');
if (ok) {
    deleteItem();
} else {
    console.log('キャンセルされた');
}
// 戻り値: true (OK) or false (Cancel / Esc / ×)

// 3. prompt: 入力
const name = prompt('お名前を入力してください', '匿名');
if (name !== null) {
    console.log('入力された:', name);
} else {
    console.log('キャンセル');
}
// 戻り値: 入力文字列 or null

典型的な使い方(削除確認)

<!-- インライン -->
<form action="/delete" method="POST"
      onsubmit="return confirm('本当に削除しますか?')">
    <button>削除</button>
</form>

<!-- イベントリスナー -->
<button id="delete-btn">削除</button>
<script>
document.getElementById('delete-btn').addEventListener('click', (e) => {
    if (!confirm('元に戻せません。削除しますか?')) {
        e.preventDefault();
        return;
    }
    // 削除処理
});
</script>

ネイティブダイアログの問題点

問題詳細影響
UI を完全ブロックJavaScript の実行が停止する (同期的)SPA / アニメーションが止まる
デザイン不可OS / ブラウザのスタイルそのままブランドイメージに合わない
多重表示で「無効化チェック」Chrome は「このサイトの追加ダイアログを禁止」を出す2 回目以降表示されない可能性
モバイル UX が悪いiOS / Android で表示が画面外使い物にならないことも
非同期処理と相性悪いawait の代わりに同期ブロックパフォーマンス低下
iframe では制限クロスオリジン iframe で動かないことも埋め込みウィジェットで失敗

HTML <dialog> 要素 (推奨)

HTML5 で標準化されたネイティブダイアログ。Promise ベースで非同期処理しやすい:

<dialog id="confirm-dialog">
    <form method="dialog">
        <p>本当に削除しますか?</p>
        <menu>
            <button value="cancel">キャンセル</button>
            <button value="ok" autofocus>OK</button>
        </menu>
    </form>
</dialog>

<button id="open-btn">削除</button>

<script>
const dlg = document.getElementById('confirm-dialog');

document.getElementById('open-btn').addEventListener('click', () => {
    dlg.showModal();  // ★ モーダル表示
});

dlg.addEventListener('close', () => {
    if (dlg.returnValue === 'ok') {
        console.log('削除実行');
    } else {
        console.log('キャンセル');
    }
});

// Promise でラップ
function confirmDialog(message) {
    return new Promise((resolve) => {
        dlg.querySelector('p').textContent = message;
        dlg.showModal();
        dlg.addEventListener('close', () => {
            resolve(dlg.returnValue === 'ok');
        }, { once: true });
    });
}

// 使い方
const ok = await confirmDialog('削除しますか?');
if (ok) { /* ... */ }
</script>

SweetAlert2 (人気ライブラリ)

<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
const result = await Swal.fire({
    title: '本当に削除しますか?',
    text: 'この操作は元に戻せません',
    icon: 'warning',
    showCancelButton: true,
    confirmButtonText: '削除する',
    cancelButtonText: 'キャンセル',
    confirmButtonColor: '#d33',
});

if (result.isConfirmed) {
    await Swal.fire('削除しました', '', 'success');
}

// トースト風通知
Swal.fire({
    toast: true,
    position: 'top-end',
    icon: 'success',
    title: '保存しました',
    timer: 3000,
    showConfirmButton: false,
});
</script>

React でのカスタムモーダル

import { useState } from 'react';

function ConfirmModal({ open, message, onConfirm, onCancel }) {
    if (!open) return null;
    return (
        <div className="modal-backdrop">
            <div className="modal">
                <p>{message}</p>
                <button onClick={onConfirm}>OK</button>
                <button onClick={onCancel}>Cancel</button>
            </div>
        </div>
    );
}

function DeleteButton() {
    const [open, setOpen] = useState(false);
    return (
        <>
            <button onClick={() => setOpen(true)}>削除</button>
            <ConfirmModal
                open={open}
                message="削除しますか?"
                onConfirm={() => { doDelete(); setOpen(false); }}
                onCancel={() => setOpen(false)}
            />
        </>
    );
}

Vue.js でのカスタムモーダル

<template>
    <button @click="show = true">削除</button>
    <div v-if="show" class="modal">
        <p>削除しますか?</p>
        <button @click="confirm">OK</button>
        <button @click="show = false">Cancel</button>
    </div>
</template>

<script setup>
import { ref } from 'vue';
const show = ref(false);
const emit = defineEmits(['confirmed']);
function confirm() {
    emit('confirmed');
    show.value = false;
}
</script>

アクセシビリティ (a11y) 配慮

  • カスタムモーダルには role="dialog" + aria-modal="true"
  • キーボードでフォーカストラップ (Tab が外に出ないように)
  • Esc キーで閉じられるように
  • 背景に aria-hidden="true" をかけて読み上げ阻止
  • ネイティブ <dialog>これら全部自動でやってくれる

選択指針

シチュエーション推奨
社内ツール / プロトタイプconfirm() でOK
モダンブラウザ対応の Web アプリ<dialog> 要素
美しいデザイン重視SweetAlert2 / カスタムモーダル
React / Vue / Svelte SPAコンポーネント化されたカスタムモーダル
IE11 サポート(既に終了)jQuery UI Dialog / Bootstrap Modal

FAQ

Q: confirm() で「キャンセル」を Esc キーで返せる?
A: 多くのブラウザで Esc は Cancel (false) 扱い。× ボタンも同じく false。

Q: <dialog> はどこから使える?
A: Chrome 37+ / Firefox 98+ / Safari 15.4+。2024 年以降は主要モダンブラウザ全対応

Q: confirm を await 風に書ける?
A: confirm() 自体は同期。await したいなら <dialog> や SweetAlert2 のような Promise ベース API を使ってください。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 記述方法
  2. コメント
  3. 変数の宣言
  4. 関数
  5. 演算子
  6. 条件文
  7. 配列
  8. 連想配列
  9. ループ処理
  10. 非同期処理
  11. 同期処理
  12. 確認ウィンドウを表示する方法
  13. 文字の置換
  14. base urlを取得する方法
  15. formのsubmit前にjavascriptを呼び出す方法
  16. undefinedのイコール判定
  17. Javascript のみで form を post で submit する方法

最近更新/作成されたページ