LoginSignup
1
3

More than 5 years have passed since last update.

HTML の input に入力された Email のバリデーションをフォーカスアウト時に行うスクリプト

Posted at

ウェブのフォームでメールアドレスの形式を確認するときに、HTML 属性で type="email" を指定しておくと、メールアドレスのチェックをしてくれます。

ただこの機能、 "foge@fuga" のようなものも通してしまって結構緩めなんですよね。

で、もうちょっと厳密に確認するためのスクリプトを探すと jQuery のプラグインが多いんですが、ピュアな JavaScript のものがほしいなと思いました。

<meta charset="utf-8">
<style>
  form {
    margin: 30px;
  }

  form > div {
    margin-bottom: 1em;
  }

  label {
    margin-right: .5em;
  }

  label::after {
    content: ":";
  }

  input,textarea,button {
    border-radius: 3px;
    font-size: 12pt;
    padding: .2em .8em;
  }

  button {
    cursor: pointer;
  }

  .sng-email-alert {
    color: #F00;
    font-weight: bold;
    margin-left: 1em;
  }
</style>
<form action="#">
  <div>
    <label for="email">Email</label>
    <input type="email" name="email" id="email" class="sng-email-check">
    <span class="sng-email-alert">正しいメールアドレスを入力して下さい</span>
  </div>

  <div>
    <button type="button">入力内容を送信する</button>
  </div>
</form>

<script>
  // script を初期化する
  window.onload = function() {
    SngEmailChecker({
      fadeInTime: '200ms',
      fadeOutTime: '200ms',
      borderNotification: true
    });
  }  
</script>
.sng-email-alert {
  opacity: 0;
  transition-property: opacity;
}

.sng-email-alert.sng-alert-show {
  opacity: 1;
  transition-property: opacity;
}

input.sng-email-check {
  transition-property: box-shadow;
}

input.incorrectValue {
  box-shadow: 0 0 3px 3px rgba(255, 60, 30, .9);
  transition-property: box-shadow;
}

input.incorrectValue:focus {
  outline: 0;
}
(function(global) {
  var SngEmailChecker = (function() {
    // メールアドレス判定用の正規表現
    // 参考: http://emailregex.com/
    var emailExpression = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
        emailInputs = Array.prototype.slice.call(document.getElementsByClassName('sng-email-check')),
        alertBoxes = Array.prototype.slice.call(document.getElementsByClassName('sng-email-alert')),
        globalConfig = {}

    function SngEmailChecker(config) {
      if (! config) config = {};
      globalConfig['fadeInTime'] = config.fadeInTime || '200ms';
      globalConfig['fadeOutTime'] = config.fadeOutTime || '200ms';
      globalConfig['borderNotification'] = config.borderNotification === undefined || config.borderNotification;

      emailInputs.map(function(elm) {
        elm.addEventListener('blur', onFocusOut);
      });
    }

    function onFocusOut() {
      var value = this.value;
      var isCorrect = emailExpression.test(value);
      alertBoxes.map(function(elm) {
        var classList = elm.classList;
        if (isCorrect) {
          elm.style['transition-duration'] = globalConfig.fadeOutTime;
          classList.remove('sng-alert-show');
        } else {
          elm.style['transition-duration'] = globalConfig.fadeInTime;
          classList.add('sng-alert-show');
        }
      });

      if (globalConfig.borderNotification) {
        emailInputs.map(function(elm) {
          if (isCorrect) {
            elm.style['transition-duration'] = globalConfig.fadeOutTime;
            elm.classList.remove('incorrectValue');
          } else {
            elm.style['transition-duration'] = globalConfig.fadeInTime;
            elm.classList.add('incorrectValue');
          }
        });
      }
    }
    return SngEmailChecker;
  }());

  global.SngEmailChecker = SngEmailChecker;
}(this));

CodePen にデモを置いておきます。

See the Pen SNGEmailValidation by Shingo Matsui (@shingorow) on CodePen.

世の中にはキーをタイプする度にチェックするものが結構ありますが、個人的にちょっとしつこすぎるなぁと思うのでフォーカスが外れたときのみチェックするようにしています。

使い方は、

  1. JavaScript と CSS ファイルを読み込む
  2. チェックしたい INPUT 要素にクラス "sng-email-check" を、アラートとして表示する要素にクラス "sng-email-alert" を設定
  3. 任意のタイミングで関数を実行するスクリプトを書く
  4. オプションで関数にパラメータを設定する

と言った感じ。

パラメーターは


{
  fadeInTime: '200ms', // メッセージやインプット要素のシャドウが表示されるまでの時間
  fadeOutTime: '200ms', // メッセージやインプット要素のシャドウが消えていくまでの時間
  boarderNotification: true // インプット要素のシャドウを表示するか否か
}

を設定できます。

引数を省略すると上記の値がデフォルト値として設定されます。

勉強も兼ねて作ったものなので、実運用にあたっては jQuery プラグインなどを探したほうがいいかもしれません。

Bootstrap とか使うときにどうせ jQuery 必要になりますしねぇ。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3