See the Pen Form for Email by kimmy (@kimmy) on CodePen.
タイトルのとおりです。
@以下の一文字をタイプしたときに、
@gmail.com, @yahoo.co.jp, @hotmail.co.jp, @docomo.ne.jp, @ezweb.ne.jp, @softbank.ne.jp をサジェストします。
ソースコード
HTML
<div class="input-box"> <input type="text" placeholder="E-Mail" class="input"/> <div data-domain="" class="suggest"><span class="btn close">×</span></div> </div>
SCSS
body { background: #ECEFF1; } .input-box { $domain : "gmail.com", "yahoo.co.jp", "hotmail.co.jp", "docomo.ne.jp", "ezweb.ne.jp", "softbank.ne.jp"; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; width: 600px; height: 60px; .input { box-sizing: border-box; display: block; margin: 0 auto 40px; border: none; border-radius: 10px; padding: 20px; width: 100%; height: 60px; font: 20px "Avenir Next"; box-shadow: 0 0 2px rgba(0, 0, 0, .5) inset; -webkit-appearance: none; &:focus { outline: none; } } .suggest { display: none; position: absolute; bottom: -40px; right: 0; padding: 4px 56px 4px 4px; border: solid 1px #90CAF9; border-radius: 4px; color: #1E88E5; font: 20px "Avenir Next"; background: #fff; cursor: pointer; -webkit-user-select: none; &:hover { color: #fff; background: #90CAF9; } @each $key in $domain { &[data-domain="#{$key}"] { display: block; &:before { content: "@#{$key}"; } } } .btn { box-sizing: border-box; position: absolute; top: 50%; right: 8px; margin-top: -8px; width: 16px; height: 16px; border-radius: 50%; color: #B0BEC5; font-size: 10px; line-height: 16px; text-align: center; background: #ECEFF1; } &.on { display: block; } } }
JavaScript
(function(win) { "use strict"; win.App = {}; })(this); (function(win, doc, ns, $) { "use strict"; function EmailInput(elm) { var that = this; _init(); function _init() { that.input = elm.querySelector(".input"); that.suggest = elm.querySelector(".suggest"); that.timer = null; that._clearSaddest = that._clearSaddest.bind(that); that._handleKeyUp = that._handleKeyUp.bind(that); that.input.addEventListener("focus", _handleFocus, false); that.input.addEventListener("blur", _handleBlur, false); that.suggest.addEventListener("click", _handleClick, false); } function _handleFocus() { that._handleFocus(); } function _handleBlur() { that._handleBlur(); } function _handleClick(evt) { that._handleClick(evt); } } EmailInput.CONST = { DOMAIN_OBJ : { g : ["gmail.com"], y : ["yahoo.co.jp"], h : ["hotmail.co.jp"], d : ["docomo.ne.jp"], e : ["ezweb.ne.jp"], s : ["softbank.ne.jp"] } }; EmailInput.prototype._displaySaddest = _displaySaddest; EmailInput.prototype._clearSaddest = _clearSaddest; EmailInput.prototype._handleFocus = _handleFocus; EmailInput.prototype._handleBlur = _handleBlur; EmailInput.prototype._handleKeyUp = _handleKeyUp; EmailInput.prototype._handleClick = _handleClick; EmailInput.prototype._checkDomain = _checkDomain; function _displaySaddest(domain) { var that = this; that.suggest.setAttribute("data-domain", domain); } function _clearSaddest() { var that = this; that._displaySaddest(""); } function _handleFocus() { var that = this; doc.addEventListener("keyup", that._handleKeyUp, false); } function _handleBlur() { var that = this; doc.removeEventListener("keyup", that._handleKeyUp, false); that.timer = setTimeout(that._clearSaddest, 200); // suggestをタップした際の対策 } function _handleClick(evt) { var that = this, domain; if (!evt.target.classList.contains("btn")) { domain = that.suggest.getAttribute("data-domain"); that.input.value = that.input.value.replace(/\@.*$/, "@" + domain); } that._clearSaddest(); } function _handleKeyUp() { var that = this; that._checkDomain(that.input.value); } function _checkDomain(txt) { var that = this, domain = "", regExp; $.each(EmailInput.CONST.DOMAIN_OBJ, function(key, val) { regExp = new RegExp("[a-zA-Z0-9]\@" + key); if (regExp.test(txt)) { domain = EmailInput.CONST.DOMAIN_OBJ[key][0]; } }); if (domain) { that._displaySaddest(domain); } else { that._clearSaddest(); } } ns.EmailInput = EmailInput; })(this, document, App, jQuery); (function EmailInput(win, doc, ns) { "use strict"; new ns.EmailInput(doc.querySelector(".input-box")); })(this, document, App);
わりと便利に使えます。