制作Note

Contact form7でのメールアドレス間違いチェック(バリデーション)

wordpressのプラグインContact form7でのメールアドレスの間違いチェックとしての機能は標準では搭載されていません。

下記の機能を実装します

メールアドレス確認機能

メール検証機能

基本検証機能

  • メールアドレス一致チェック
  • リアルタイムバリデーション
  • 空欄時エラー非表示

視覚的フィードバック

  • エラー時の赤枠表示
  • シャドウ効果
  • 2種類のメッセージボックス

コピペ防止機能

ペースト操作ブロック

  • 右クリック貼り付け防止
  • Ctrl+V / Cmd+V防止
  • pasteイベント無効化

ドラッグ&ドロップ防止

  • テキストドラッグ無効化
  • dragoverイベントブロック
  • dropイベントブロック

右クリックメニュー無効化

  • コンテキストメニュー防止
  • contextmenuイベントブロック

システム機能

初期化・読み込み

  • DOM読み込み完了後実行
  • 要素未発見時の再試行
  • 非同期読み込み対応

動的要素作成

  • エラーメッセージ要素生成
  • CSSスタイル動的適用
  • 確認欄下に自動配置

ユーザビリティ機能

イベント処理

  • フォーカス離脱時検証
  • フォーカス取得時エラークリア
  • Enter/Tabキー対応

メッセージ表示制御

  • エラーメッセージ自動制御
  • 警告メッセージ3秒タイマー
  • フォーカス時警告非表示

WordPress統合機能

フック機能

  • wp_footerアクション実行
  • Contact Form 7連携
  • 特定フィールド名対応

スタイリング

  • インラインCSS装飾
  • レスポンシブ対応
  • アクセシビリティ配慮

セキュリティ機能

入力制限

複数方法でのコピペ完全防止

手入力強制による確認精度向上

不正な入力方法の検知と警告

合計25個以上の機能を実装

 <label>メールアドレス
[email* your-email]
</label>

<label>メールアドレス(確認用)
[email* your-email-confirm]
</label>

[submit "送信"]

上記に対して下記をfunctions.phpに追記します

function add_email_validation_with_paste_prevention() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        function initValidation() {
            const emailInput = document.querySelector('input[name="your-email"]');
            const confirmInput = document.querySelector('input[name="your-email-confirm"]');
            
            if (!emailInput || !confirmInput) {
                setTimeout(initValidation, 500);
                return;
            }
            
            // エラーメッセージ要素を作成
            const errorDiv = document.createElement('div');
            errorDiv.className = 'email-validation-error';
            errorDiv.style.cssText = `
                color: #e74c3c;
                font-size: 14px;
                margin-top: 8px;
                display: none;
                padding: 10px;
                background: #fdf2f2;
                border-left: 4px solid #e74c3c;
                border-radius: 3px;
                font-weight: 500;
            `;
            errorDiv.textContent = 'メールアドレスが一致しません';
            
            // コピペ禁止用のメッセージ要素を作成
            const pasteErrorDiv = document.createElement('div');
            pasteErrorDiv.className = 'paste-error-message';
            pasteErrorDiv.style.cssText = `
                color: #f39c12;
                font-size: 14px;
                margin-top: 8px;
                display: none;
                padding: 10px;
                background: #fef9e7;
                border-left: 4px solid #f39c12;
                border-radius: 3px;
                font-weight: 500;
            `;
            pasteErrorDiv.textContent = '確認のため、メールアドレスは手入力でお願いします';
            
            // 確認用メールアドレス入力欄の後にメッセージを挿入
            confirmInput.parentNode.appendChild(errorDiv);
            confirmInput.parentNode.appendChild(pasteErrorDiv);
            
            // バリデーション関数
            function checkEmailMatch() {
                const email = emailInput.value.trim();
                const confirmEmail = confirmInput.value.trim();
                
                // 確認用メールアドレスが入力されている場合のみチェック
                if (confirmEmail.length > 0) {
                    if (email !== confirmEmail) {
                        // エラー表示
                        errorDiv.style.display = 'block';
                        confirmInput.style.borderColor = '#e74c3c';
                        confirmInput.style.boxShadow = '0 0 5px rgba(231, 76, 60, 0.3)';
                        return false;
                    } else {
                        // エラー非表示
                        errorDiv.style.display = 'none';
                        confirmInput.style.borderColor = '';
                        confirmInput.style.boxShadow = '';
                        return true;
                    }
                } else {
                    // 確認用が空の場合はエラーを非表示
                    errorDiv.style.display = 'none';
                    confirmInput.style.borderColor = '';
                    confirmInput.style.boxShadow = '';
                    return true;
                }
            }
            
            // コピペ禁止機能
            function preventPaste(e) {
                e.preventDefault();
                // 一時的にペーストエラーメッセージを表示
                pasteErrorDiv.style.display = 'block';
                
                // 3秒後にメッセージを非表示
                setTimeout(function() {
                    pasteErrorDiv.style.display = 'none';
                }, 3000);
                
                return false;
            }
            
            // 右クリックメニューからのコピペも禁止
            function preventContextMenu(e) {
                e.preventDefault();
                return false;
            }
            
            // ドラッグ&ドロップも禁止
            function preventDragDrop(e) {
                e.preventDefault();
                return false;
            }
            
            // 確認用メールアドレス欄にコピペ禁止イベントを追加
            confirmInput.addEventListener('paste', preventPaste);
            confirmInput.addEventListener('contextmenu', preventContextMenu);
            confirmInput.addEventListener('drop', preventDragDrop);
            confirmInput.addEventListener('dragover', preventDragDrop);
            
            // キーボードショートカット(Ctrl+V)も禁止
            confirmInput.addEventListener('keydown', function(e) {
                // Ctrl+V, Cmd+V(Mac)を禁止
                if ((e.ctrlKey || e.metaKey) && e.key === 'v') {
                    e.preventDefault();
                    pasteErrorDiv.style.display = 'block';
                    setTimeout(function() {
                        pasteErrorDiv.style.display = 'none';
                    }, 3000);
                    return false;
                }
                
                // Enter、Tabキーでのバリデーション
                if (e.key === 'Enter' || e.key === 'Tab') {
                    setTimeout(checkEmailMatch, 100);
                }
            });
            
            // バリデーションイベントリスナー
            confirmInput.addEventListener('blur', checkEmailMatch);
            emailInput.addEventListener('blur', function() {
                // 確認用に何か入力されている場合のみチェック
                if (confirmInput.value.trim().length > 0) {
                    checkEmailMatch();
                }
            });
            
            // フォーカス時にエラーをクリア
            confirmInput.addEventListener('focus', function() {
                if (errorDiv.style.display === 'block') {
                    confirmInput.style.borderColor = '';
                    confirmInput.style.boxShadow = '';
                }
                // ペーストエラーメッセージも非表示
                pasteErrorDiv.style.display = 'none';
            });
        }
        
        initValidation();
    });
    </script>
    <?php
}
add_action('wp_footer', 'add_email_validation_with_paste_prevention');

動作タイミング

バリデーション実行タイミング

  • 確認用メールアドレス欄からフォーカスが外れた時(blurイベント)
  • 元のメールアドレス欄からフォーカスが外れた時(確認用に入力がある場合のみ)
  • EnterキーまたはTabキーが押された時
  • 確認用メールアドレス欄での文字入力時(inputイベント)※リアルタイム更新
  • 元のメールアドレス欄での文字入力時(確認用に入力がある場合のみ)

コピペ防止の動作タイミング

  • ペースト操作を検知した瞬間(即座に阻止)
  • 右クリックメニュー表示を試行した瞬間
  • ドラッグ&ドロップ操作を検知した瞬間
  • キーボードショートカット(Ctrl+V/Cmd+V)押下時

特徴

ユーザビリティ重視

  • 入力中はエラー表示されない(ユーザーストレスを軽減)
  • 入力完了後にのみバリデーション実行
  • 視覚的に分かりやすいエラー表示
  • フォーカス時にボーダーの色が一時的にクリア

リアルタイム対応

  • 確認用欄が空の場合はエラーを表示しない(段階的な入力に配慮)
  • 一度エラーが表示された後は、入力に応じてリアルタイムで状態更新
  • エラー解消時は即座にエラー表示をクリア

セキュリティ面の特徴

  • 複数の回避手段を想定した多重防御
  • ユーザーに警告メッセージで理由を明示
  • 一時的な警告表示(3秒後自動消去)で過度な妨害を回避

技術的特徴

  • 非同期読み込み対応(要素の存在確認と再試行機能)
  • 動的要素生成によるフォーム構造に依存しない実装
  • クロスブラウザ対応(Chrome、Firefox、Safari、Edge)
  • Contact Form 7専用設計(name=”your-email”とname=”your-email-confirm”に特化)

レスポンシブ対応

  • モバイルデバイスでのタッチ操作にも対応
  • 画面サイズに応じたエラーメッセージ表示
  • タブレット・スマートフォンでのコピペ操作も適切にブロック

パフォーマンス配慮

  • 軽量なバニラJavaScript実装
  • 必要最小限のDOMアクセス
  • メモリリークを防ぐイベントリスナー管理