フォームバリデーションの実装
ユーザーデータの収集は多くのWebアプリケーションの中核をなします。クライアントサイドでのバリデーションは、ユーザーに即座にフィードバックを提供し、ユーザー体験(UX)を向上させるために不可欠です。ただし、クライアントサイドのバリデーションは容易に回避可能であるため、セキュリティの観点からはサーバーサイドでの検証が必須となります。
基本的なバリデーションのセットアップ
まず、フォームの基盤となるHTMLとCSSを準備します。各入力フィールドには、検証ルールに対応したクラス(例: required, email)を付与します。
jQueryを使用して、フォーム送信時に各入力フィールドを走査し、検証ルールを適用します。エラーメッセージはDOM要素として動的に追加・削除します。
$(function() {
const $submitBtn = $('.submit-btn');
const $form = $('#registrationForm');
$submitBtn.on('click', function(e) {
e.preventDefault();
let hasErrors = false;
const $inputs = $('input');
// 既存のエラー表示をクリア
$('.input-group').removeClass('error-state');
$('.error-msg').remove();
$inputs.each(function() {
const $input = $(this);
const val = $input.val();
// 必須項目チェック
if ($input.hasClass('required') && val.trim() === '') {
showError($input, '必須項目です');
hasErrors = true;
}
// 数値チェック
else if ($input.hasClass('numeric') && val !== '' && !isNumeric(val)) {
showError($input, '数値のみ入力可能です');
hasErrors = true;
}
// メールチェック
else if ($input.hasClass('email') && val !== '' && !isValidEmail(val)) {
showError($input, '有効なメールアドレスを入力してください');
hasErrors = true;
}
// クレジットカードチェック
else if ($input.hasClass('credit-card') && val !== '' && !isValidCard(val)) {
showError($input, '無効なカード番号です');
hasErrors = true;
}
// 日付チェック (DD/MM/YYYY)
else if ($input.hasClass('date') && val !== '' && !isValidDate(val)) {
showError($input, '日付形式が不正です');
hasErrors = true;
}
});
if (!hasErrors) {
$form.submit();
}
});
function showError($el, msg) {
$el.parent().addClass('error-state');
$el.after('<div class="error-msg">' + msg + '</div>');
}
function isNumeric(val) {
return !isNaN(parseFloat(val)) && isFinite(val);
}
function isValidEmail(val) {
return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(val);
}
function isValidCard(val) {
// 主要カードブランド対応の簡易正規表現
return /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$/.test(val);
}
function isValidDate(val) {
if (!/^\d{2}\/\d{2}\/\d{4}$/.test(val)) return false;
const parts = val.split('/');
const day = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10) - 1; // JSの月は0始まり
const year = parseInt(parts[2], 10);
const date = new Date(year, month, day);
return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day;
}
});
リアルタイムバリデーション
ユーザーが入力中にエラーを通知するために、keyupイベントを利用します。検証ロジックを関数化して再利用することでコードを効率化します。
$('input').on('keyup', function() {
validateField($(this));
});
function validateField($input) {
const val = $input.val();
// 上記の検証ロジックを個別に適用し、エラー表示を更新
// 実装略: 上記のループ処理内のロジックを参照
}
パスワード強度インジケーター
パスワードの安全性を高めるため、文字数、大文字・小文字、数字、記号の含有をスコア化し、リアルタイムで強度を表示します。
$('#password').on('keyup', function() {
let score = 0;
const pass = $(this).val();
if (pass.length > 6) score++;
if (pass.length > 10) score++;
if (/[A-Z]/.test(pass) && /[a-z]/.test(pass)) score++;
if (/[0-9]/.test(pass)) score++;
if (/[^A-Za-z0-9]/.test(pass)) score++;
const width = (score / 5) * 100;
$('#strength-bar').css('width', width + '%').attr('class', 'strength-' + score);
});
入力制限とスパム対策
特定の文字(例:ユーザー名に記号を許可しない)の入力をブロックするには、keypressイベントを使用します。また、簡単な計算問題などをスパムボット対策として組み込むことができます。
// ユーザー名は英数字のみ
$('#username').on('keypress', function(e) {
const char = String.fromCharCode(e.which);
if (!/[a-zA-Z0-9]/.test(char)) {
e.preventDefault();
}
});
ユーザーインターフェースコンポーネントの構築
jQueryを活用して、動的でインタラクティブなUIコンポーネントを構築します。
CSSの操作
css()メソッドを使用して、ユーザーの操作に応じてスタイルを動的に変更できます。例えば、ドロップダウン選択に応じてフォントサイズや色を変更するなどです。
ニュースティッカー
setIntervalとアニメーションを組み合わせて、ニュース見出しを順に表示するティッカーを作成します。マウスオーバーで一時停止する機能も実装可能です。
let tickerTimer;
function startTicker() {
tickerTimer = setInterval(function() {
const $first = $('#ticker li:first');
$first.slideUp(function() {
$(this).appendTo('#ticker').slideDown();
});
}, 3000);
}
$('#ticker-container').hover(function() {
clearInterval(tickerTimer);
}, function() {
startTicker();
});
startTicker();
スティッキー要素とスムーズスクロール
スクロール量を監視し、特定の位置で要素を固定表示(position: fixed)させます。また、アンカーリンクのクリック時にページ内遷移をアニメーションさせると、ユーザーは現在の位置関係を把握しやすくなります。
// スムーズスクロール
$('a[href^="#"]').on('click', function(e) {
e.preventDefault();
const target = $(this.hash);
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 800);
}
});
// スティッキー要素
const $sticky = $('.sidebar');
const stickyTop = $sticky.offset().top;
$(window).scroll(function() {
if ($(window).scrollTop() >= stickyTop) {
$sticky.addClass('fixed');
} else {
$sticky.removeClass('fixed');
}
});
ドラッグ&ドロップ
マウスイベント(mousedown, mousemove, mouseup)をハンドリングして、要素を自由に移動させる機能を実装します。境界チェックを行うことで、親要素の外に出ないように制御できます。
$('.draggable').on('mousedown', function(e) {
const $this = $(this);
const offset = $this.offset();
const startX = e.pageX - offset.left;
const startY = e.pageY - offset.top;
$(document).on('mousemove.drag', function(e) {
$this.css({
left: e.pageX - startX,
top: e.pageY - startY
});
}).on('mouseup.drag', function() {
$(document).off('.drag');
});
});
アコーディオンとタブ
コンテンツの表示・非表示を切り替えるUIです。アコーディオンはslideToggleを、タブはアクティブなコンテンツのみを表示し、それ以外を隠すロジックを利用します。
モーダルウィンドウ
オーバーレイ背景とコンテンツ領域を持つポップアップを作成します。中央揃えの計算や、閉じるボタン、背景クリックでの終了処理などを実装します。
function openModal() {
const $modal = $('#modal');
const $overlay = $('#overlay');
// 中央配置計算
$modal.css({
top: ($(window).height() - $modal.outerHeight()) / 2,
left: ($(window).width() - $modal.outerWidth()) / 2
});
$overlay.fadeIn();
$modal.fadeIn();
}
function closeModal() {
$('#overlay, #modal').fadeOut();
}
これらのコンポーネントは、現代的なWebサイトにおいてユーザーの操作性を大幅に向上させる基盤となります。