Email Suggest 邮箱输入提示

1621次阅读  |  发布于5年以前

最近的项目会用到登录框邮箱输入提示的功能,于是花了点时间仿照新浪微博的登录框的邮箱提示效果自己写了一个,效果和新浪微博的基本一致,但是实现原理可能会有区别。

查看演示

HTML结构部分:


    <div id="login_box">
      <div>
        <label for="email">电子邮箱:</label>
        <input type="text" id="email" autocomplete="off" />
      </div>
      <ul id="email_list">
        <li>请选择邮箱类型</li>
        <li></li>
        <li>@163.com</li>
        <li>@126.com</li>
        <li>@qq.com</li>
        <li>@yahoo.com.cn</li>
        <li>@gmail.com</li>
        <li>@sohu.com</li>
        <li>@hotmail.com</li>
      </ul>
    </div>

与新浪微博不同的是,我将邮箱后缀都先写在了结构中,然后用把邮箱后缀取出来存到一个数组中。上面input标签中的autocomplete="off"属性是用来关闭浏览器默认的cookie提示的,如果不关闭这个提示将会弹出2个层,新浪微博的就没有关闭,这应该算是一个BUG吧。

CSS样式部分:


    #login_box { position:relative; }
    .clearfix label { font-size:14px; float:left; }
    .clearfix { height:30px; line-height:30px; }
    .clearfix:after { height:0; visibility:hidden; content:"."; overflow:hidden; display:block; }
    #email { width:180px; height:18px; border:1px solid #74c9e6; padding:5px 6px; background:#fff; margin-left:10px; -moz-border-radius:2px; border-radius:2px; font-family:arial; float:left; }
    #email_list { width:192px; list-style:none; border:1px solid #74c9e6; -moz-border-radius:0 0 2px 2px; border-radius:2px; position:absolute; top:29px; left:80px; background:#fff; display:none; }
    #email_list li { width:100%; height:30px; line-height:30px; text-indent:10px; cursor:pointer; overflow:hidden; }
    #email_list li.first_li { cursor:default; }
    #email_list .current { background:#baeafb; }

提示框默认状态下是隐藏的,只有当检测到输入框有输入的时候才显示。

JavaScript部分:


    <script type="text/javascript">
    //<![CDATA[
    (function(){

    /* 初始化 */
    var emailInput = document.getElementById("email"),
        list = document.getElementById("email_list"),
        items = list.getElementsByTagName("li"),
        item1 = items[1],
        len = items.length,
        suffix = [],
        newSuffix, indexA, indexB,
        highlight = "current",
        isIE = navigator.userAgent.toLowerCase().indexOf("msie") != -1,
        clearClassname = function(){
            for(var i = 1,el;i < len && (el = items[i]);i ){
                el.className = "";
            }
        };

    /* 将邮箱后缀存放到一个新数组中 */    
    for(var j = 1,el;j < len && (el = items[j]);j ){
        suffix[suffix.length ] = el.innerHTML;
    }

    /* 邮箱输入框绑定keyup事件 */    
    emailInput.onkeyup = suggest;

    /* suggest核心部分 */
    function suggest(event){
        var e = event || window.event,
            eCode = e.keyCode,
            val = this.value,
            index = val.indexOf("@"),
            isIndex = index !== -1;

        clearClassname();
        //输入框不为空
        if(val){ 
            item1.className = highlight;
            list.style.display = "block";
            for(var i = 1,el;i < len && (el = items[i]);i ){
                el.onmouseover = function(){
                    clearClassname();
                    item1.className = "";
                    this.className = highlight;
                    indexA = 1;
                    indexB = 0;
                }
                el.onmouseout = function(){
                    this.className = "";
                    item1.className = highlight;
                }
                el.onclick = function(){
                    emailInput.value = this.innerHTML;
                }
            }
        }
        //输入框为空
        else{   
            item1.className = "";
            for(var i = 1,el;i < len && (el = items[i]);i ){
                el.onmouseout = el.onmouseover = el.onclick = null;
            }
            if(eCode === 38  || eCode === 40 || eCode === 13) return;
        }

        item1.innerHTML = val;
        newSuffix = []; //初始化空数组
        for(var i = 1, el ;i < len && (el = items[i]);i ){
            /* 以邮箱后缀和输入框中@标志符后是否
             有相同的字符串来显示或隐藏该元素 */
            el.style.display = isIndex && el.innerHTML.indexOf(val.substring(index)) === -1 ? "none" : "block";
            if( i > 1 ) el.innerHTML = (isIndex ? val.substring(0,index) : val) suffix[i-1];
            /* 出现@标志符时将新的元素的排列顺序
             存放到空数组newSuffix中 */
            if((!isIE && window.getComputedStyle(el,null).display === "block") || (isIE && el.currentStyle.display === "block")){ 
                newSuffix[newSuffix.length ] = i;
            }
        }

        /* 判断按键 */
        switch (eCode){
            case 38 : //上方向键
                keyMove(-1);
                break;
            case 40 : //下方向键
                keyMove(1);
                break;      
            case 13 : //回车键
                getVal();
                break;  
            default:
                indexA = 1;
                indexB = 0;
                return; 
        }
    }

    /* 方向键控制元素的高亮效果 */
    function keyMove(n){    
        var newLen = newSuffix.length;      
        if(newLen > 0 && newLen < 8 ){
            items[newSuffix[indexB]].className = item1.className = "";
            indexB = n;
            if (indexB === newLen) indexB -= newLen;
            else if (indexB < 0) indexB = newLen;
            items[newSuffix[indexB]].className = highlight;
        }           
        else{
            items[indexA].className = item1.className = "";
            indexA = n;
            if (indexA === len) indexA -= len - 1;
            else if (indexA === 0) indexA = len - 1;
            items[indexA].className = highlight;
        }
    }

    /* 获取当前高亮元素的值 */
    function getVal(){
        var newLen = newSuffix.length;
        emailInput.value = newLen > 0 && newLen < 8 ? items[newSuffix[indexB]].innerHTML : items[indexA].innerHTML;
        list.style.display = "none";
    }

    /* 关闭提示层 */
    document.onclick = function(e){
        e = e || window.event;
        var eNode = e.target ? e.target : e.srcElement;
        if(eNode !== emailInput && eNode !== items[0]){
            list.style.display = "none";
        }
    }

    })();
    //]]>
    </script>

代码写得比较繁琐,但是功能至少还是实现了,也算是学习了JavaScript的按键事件。有不足之处或者发现有BUG,望各位同志踊跃拍砖。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8