読者です 読者をやめる 読者になる 読者になる

アラタナエンジニアブログ

aratana Engineer's Blog

【jQueryPlugin】簡単に年齢チェックが出来るAgeCheck.js

みなさん、こんにちは。
開発チームの黒木です。

最近は何から何までネットで購入できるようになりましたね。
私自身、何か大きな買い物やレア物は基本ネットショッピングです。

今回は、ECサイトで訪問者の年齢確認をしたいという方向けに、
簡単に年齢チェックが出来るjQueryPluginをご紹介したいと思います。

AgeCheck.jsとは

ポップアップウィンドウを表示させて、入力された生年月日から年齢を自動計算し、
指定された年齢以上の場合は、指定されたURLへ遷移させるというものです。
デモサイト
f:id:a_kuror:20150411101001g:plain
指定された年齢未満の場合は、エラーを表示します。

使い方

導入したいサイトの対象ページに下記を追加する。
AgeCheck.jsのダウンロードはこちらから

  1. jQueryライブラリを追加する
  2. AgeCheck.jsのプラグインを追加する
  3. AgeCheck.jsのスタイルシートを追加する
  4. $.ageCheck()を呼び出す。
<script src="jquery.min.js"></script>
<script src="jquery.agecheck.min.js"></script>
<link href="agecheck.css" rel="stylesheet" />
$(document).ready(function(){
   $.ageCheck();
});

オプション

オプション 内容
minAge 許可する年齢を指定してください。
redirectTo 年齢確認が成功した場合に遷移させるページのURLを指定してください。
title 年齢確認のポップアップのタイトルを指定してください。
copy 年齢確認のポップアップの説明文を指定してください。

日本語化&いろいろしてみる!

とてもシンプルなプラグインなので、日本語化も簡単です。
そのほかに、実際使う際にネックになる可能性のある部分を変更してみます。

  • 日付の入力形式も「月/日/年」となっているため、「年/月/日」の形式に変更します。
  • 合わせて、基準年齢もデフォルト21歳となっているため、日本の成人の基準となる20歳に変更します。
  • 画面上に「year」「month」「day」のクラスを持つエレメントがあった場合、正常に動作しないのでid指定のセレクタで取得するように変更します。
  • 日付の妥当性チェックがないので、追加します。
  • 変更の必要がありそうなメッセージもオプション設定できるようにします。
(function ($){   
    
    $.ageCheck = function(options) {
        
        var settings = $.extend({
            minAge : 20,          
            redirectTo : '', 
            title : '年齢確認', 
            copy : 'このサイトは20歳以上の方のみご利用できます。生年月日をご入力いただき、年齢確認を実施してください。',
            successTitle : '年齢が確認されました。',
            successMsg : 'サイトの閲覧が可能です。',
            errorMsg : 'あなたの年齢では、サイトの閲覧は出来ません。'
        }, options);
        
        
        var _this = {
            month : '',  
            day : '',  
            year : '',   
            age : '',
            errors : Array(), 
            setValues : function(){
                var month = $('#checkage_month').val();
                var day = $('#checkage_day').val();
                _this.month = month;
                _this.day = day.replace(/^0+/, ''); //remove leading zero
                _this.year = $('#checkage_year').val();
            },
            validate : function(){
                _this.errors = [];
                if (/^([0-9]|[12]\d|3[0-1])$/.test(_this.day) === false) {
                    _this.errors.push('生年月日(日)が正しく入力されていません。');
                };
                if (/^(19|20)\d{2}$/.test(_this.year) === false) {
                    _this.errors.push('生年月日(年)が正しく入力されていません。');
                };
                 // 月,日の妥当性チェック 
                if ( 0 <= _this.month && _this.month <= 11 && 1 <= _this.day && _this.day <= 31 ) { 
                    var dt = new Date(_this.year, _this.month, _this.day); 
                    if(dt.getFullYear() != _this.year ||
                        dt.getMonth() != _this.month ||
                        dt.getDate() != _this.day ) {
                        _this.errors.push('入力された生年月日は正しい日付ではありません。');
                    }
                }
                _this.clearErrors();
                _this.displayErrors();
                return _this.errors.length < 1;
            }, 
            clearErrors : function(){         
                $('.errors').html('');
            }, 
            displayErrors : function(){
                var html = '<ul>';
                for (var i = 0; i < _this.errors.length; i++) {
                    html += '<li><span>x</span>' + _this.errors[i] + '</li>';
                }
                html += '</ul>';
                setTimeout(function(){$('.errors').html(html)},200);
            },
            reCenter : function (b){
                b.css("top", Math.max(0, (($(window).height() - (b.outerHeight() + 150)) / 2) + 
                                            $(window).scrollTop()) + "px");
                b.css("left", Math.max(0, (($(window).width() - b.outerWidth()) / 2) + 
                                            $(window).scrollLeft()) + "px");
            }, 
            buildHtml : function(){
            
                var copy = settings.copy; 
                var months = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'];
                var html = '';
                html += '<div class="ac-overlay"></div>';
                html += '<div class="ac-container">';
                html += '<h2>' + settings.title + '</h2>';
                html += '<p>' + copy.replace('[20]','<strong>'+settings.minAge+'</strong>'); + '</p>';
                html += '<div class="errors"></div>';
                html += '<div class="fields">';
                html += '<input id="checkage_year" class="year" maxlength="4" placeholder="1989"/>';
                html += '<select id="checkage_month" class="month">';
                for(var i=0;i<months.length;i++){
                    html += '<option value="'+ i +'">'+months[i]+'</option>'
                }
                html += '</select>';
                html += '<input id="checkage_day" class="day" maxlength="2" placeholder="01" />';
                html += '<button>Submit</button></div></div>';
                
                $('body').append(html);
                
                $('.ac-overlay').animate({
                    opacity: 0.8
                }, 500, function() {
                    _this.reCenter($('.ac-container'));
                    $('.ac-container').css({opacity: 1})
                });
                
                $(".ac-container .day, .ac-container .year").focus(function(){
                   $(this).removeAttr('placeholder');
                });
            }, 
            setAge : function(){
                _this.age = '';                 
                var birthday = new Date(_this.year, _this.month, _this.day);  
                var ageDifMs = Date.now() - birthday.getTime();
                var ageDate = new Date(ageDifMs); // miliseconds from epoch
                _this.age = Math.abs(ageDate.getUTCFullYear() - 1970);
            }, 
            setSessionStorage  : function(key, val){
                try {
                    sessionStorage.setItem(key,val);
                    return true;
                } catch (e) {
                    return false;
                }
            },
            handleSuccess : function(){                
                var successMsg = '<h3>' + settings.successTitle + '</h3><p>' + settings.successMsg + '</p>';
                $('.ac-container').html(successMsg);
                setTimeout(function(){
                    $('.ac-container').animate({'top':'-350px'},200, function(){
                         $('.ac-overlay').animate({'opacity':'0'},500, function(){
                            if (settings.redirectTo != '') {
                                window.location.replace(settings.redirectTo);
                            }else{
                                $('.ac-overlay, .ac-container').remove();
                            }
                         });
                    });
                },2000);
            }
            
        }; //end _this
         
        if(sessionStorage.getItem("ageVerified") == "true"){
            return false;
        }
        
        _this.buildHtml();  
        
        $('.ac-container button').on('click', function(){
            _this.setValues();
            if (_this.validate() === true) {
                _this.setAge();
                
                if(_this.age >= settings.minAge){
                    if(!_this.setSessionStorage("ageVerified", "true")){
                        console.log('お使いのブラウザではsessionStorageがサポートされていません。');
                    };
                    _this.handleSuccess();
                }else{
                    _this.errors.push(settings.errorMsg);
                    _this.displayErrors();
                }
            }
        });
        
        $(window).resize(function() {
            _this.reCenter($('.ac-container'));
            setTimeout(function() {
                _this.reCenter($('.ac-container'));
            }, 500);
        });
    };
}(jQuery));

こんな感じになります。
f:id:a_kuror:20150411120740p:plain

注意点

  • もしサイト全体を制限したい場合は、ヘッダーやフッター等どのページにも表示される箇所で$.ageCheck()を呼び出す必要があります。検索サイトからの訪問者等は、必ずしもトップページに遷移するとは限らないからです。
  • javascriptが無効となっているブラウザの場合は、動作しません。
  • AgeCheck.jsは、SessionStorageを使用しています。そのため、別ウィンドウでのデータ共有はできず、ブラウザを閉じると無効となってしまいます。
  • sessionStorageがサポートされていないブラウザの場合は、自動的に年齢確認成功となり、サイトの閲覧が可能となる仕様です。
  • ユーザーの年齢を保証することはできません。ユーザーが偽の生年月日を入力してもAgeCheck.jsではわかりません。

まとめ

AgeCheck.jsいかがでしたでしょうか?
注意点にも書いた通り出来ることは限られていますが、とってもシンプルな年齢チェックプラグインです。
もちろん、cssファイルもありますので、お好きなデザインに変更可能です。
実際にご使用になる場合は、もちろん十分な検証が必要ですが、こんなのやりたかったという方には、参考になるかなと思っています。


参考サイトはこちらfearlessflyer.com