为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript实现邮箱后缀提示功能

标签:
JavaScript

先来个基础的

需求

根据下面需求实现如示意图所示的邮箱输入提示功能,注意,根据要求只需实现下面功能

  • 当用户没有任何输入时,提示框消失

  • 当用户输入字符后,显示提示框,并且把用户输入的内容自动拼上邮箱后缀进行显示

  • 暂时不用考虑示意图中的红色和蓝色背景色的逻辑

  • 注意用户输入中前后空格需要去除

小优化编码

需求

如果我们输入的是 abc@1,这个时候出现的提示框内容是

  • abc@1@163.com

  • abc@1@gmail.com

  • abc@1@126.com
    ……

很明显,上面的提示框不是一个符合用户需求的提示,我们需要做一些优化:

    • 当用户输入含有 @ 符号时,我们选取用户输入的@前面的字符来和后缀拼接

需求

这下出现的提示好多了,不过用户如果已经输入了@1,说明他大概率要输入163或者126,我们需要让我们的提示更加符合用户的期望。满足以下需求:

  • 当用户输入了 @ 及部分后缀时,只从 postfixList 选取符合用户输入预期的后缀,我们以前缀匹配为要求。

  • 当用户输入不满足任何前缀匹配时,则显示全部提示

测试用例

  • 输入a@1->出现提示框,提示a@163.com, a@126.com

  • 输入a@g->出现提示框,提示a@gmail.com

  • 输入a@2->出现提示框,提示a@263.net

  • 输入a@qq->出现提示框,提示a@qq.com

  • 输入a@163.->出现提示框,提示a@163.com

  • 输入a@126.com->出现提示框,提示a@126.com

  • 输入a@qq.com (两个空格)->出现提示框,提示a@qq.com

  • 输入a@qq.comm->出现提示框,出现全部提示

代码1

复制代码

  1 <!DOCTYPE html>  2 <html>  3   4 <head>  5     <meta charset="utf-8" />  6     <title>邮箱后缀提示1-完成基本提示</title>  7       8 </head>  9  10 <body> 11     <div class="wrapper"> 12         <input type="text" id="input-email"> 13         <ul class="email-sug" id="email-sug-wrapper"> 14  15         </ul> 16     </div> 17     <script> 18         var postfixList = ["163.com", "gmail.com", "126.com", "qq.com", "263.net"]; 19         var txt = document.getElementById("input-email"); 20         var sug = document.getElementById("email-sug-wrapper"); 21          22         // keys.addEventListener("keyup",function(){ 23         //     console.log("event handle1"); 24         // }) 25         // keys.addEventListener("keypress",function(){ 26         //     console.log("event handle2"); 27         // }) 28         // keys.addEventListener("keydown",function(){ 29         //     console.log("event handle3"); 30         // }) 31         // keys.addEventListener("input",function(){ 32         //     console.log("event handle4"); 33         // }) 34  35         //经过查看各个效果,oninput效果最符合需求。 36         txt.oninput = function () { 37             console.log("event handle4"); 38             judge(); 39             add(); 40  41         } 42         function getText() { 43             var inputText = txt.value.trim(); 44             return inputText; 45         } 46         //判断是否生成新的数组 47         function postlist() { 48             var userinput = getText(); 49             var newpostlist = new Array(); 50             if (userinput.search('@') != 0) { 51                 var len = userinput.search('@'); 52                 //用来拼接的用户输入内容 = 只使用@之后的字符串 53                 var x = userinput.substring(len + 1, userinput.length); //取@之后的部分 54                 for (var i = 0; i < postfixList.length; i++) { 55                     if (postfixList[i].search(x) == 0) { 56                         newpostlist.push(postfixList[i]); 57                     } 58                 } 59                 //若@后面没有字符或者新数组newpostlist为空,就返回原来的postfixlist 60                 if (x === '' || newpostlist == '') { 61                     return postfixList; 62                 } 63                 return newpostlist; 64             } else { 65                 return postfixList; 66             } 67         } 68         //根据输入内容和匹配来生成提示数组 69         function promptContent() { 70             var x = getText(); 71             var tips = new Array(); 72             if (x.indexOf("@") != -1) { 73                 var p = x.slice(0, x.indexOf("@")); 74                 for (i = 0; i < postlist().length; i++) { 75                     tips[i] = p + "@" + postlist()[i]; 76                 } 77             } else { 78                 for (i = 0; i < postfixList.length; i++) { 79                     tips[i] = x + "@" + postfixList[i]; 80                 } 81             } 82             return tips; 83         } 84         //添加提示数组进入li 85         function add() { 86             var sug = document.getElementById("email-sug-wrapper"); 87             var tips = promptContent(); 88             while (sug.hasChildNodes()) { 89                 sug.removeChild(sug.firstChild); 90             } 91             //将之前的列表清除掉,然后重新生成新的列表 92             for (i = 0; i < tips.length; i++) { 93                 var tip_li = document.createElement("li"); 94                 tip_li.innerHTML = tips[i]; 95                 sug.appendChild(tip_li); 96             } 97         } 98  99         function judge() {100             //判空,是“”没有内容,不能为“ ”101             if (getText() == "") {102                 hide();103             } else {104                 display();105             }106 107         }108 109         function hide() {110             sug.style.display = "none";111         }112 113         function display() {114             sug.style.display = "block";115         }116     </script>117 </body>118 119 </html>

复制代码

新的需求编码

需求

上面我们只完成了提示,但提示还没有直接作用到选择中,我们现在完成以下需求:

  • 使用CSS实现:鼠标滑过提示框的某一个提示时,这个提示内容背景色变化,表示鼠标经过了这个DOM节点

  • 鼠标如果点击某个提示,则提示内容进入输入框,同时提示框消失

  • 在上个步骤结束后,在输入框中任意再输入字符或删除字符,则重新开始出现提示框

需求

尝试在输入框中输入<b>,看看提示框发生了什么

阅读

设计

我们需要在两个地方进行处理,一个是在生成提示内容那里,对于特殊字符进行转义编码,另一个是在把鼠标点击的提示框内容转回输入框时进行解码。

代码2

复制代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>邮箱后缀提示2-添加样式和监听鼠标点击和转码内容</title>
    <style>
    #input-email{
        width: 300px;
        height: 30px;
    }
    .email-sug{
        width: 300px;
        list-style: none;
        padding: 0px;
        margin: 0px;
        border: 2px solid rgba(134, 132, 132,0.3);
        border-top:none;
        display: none;        /* 初始不显示,避免边框出现 */
    }
    .email-sug li{
        width: 300px;
        height: 30px;
        background-color: #ffffff;
        color: darkgrey;
        line-height: 30px;    
    }
    .email-sug li:hover{
        background-color:pink;
    }    </style>
</head>

<body>
    <div class="wrapper">
        <input type="text" id="input-email">
        <ul class="email-sug" id="email-sug-wrapper">

        </ul>
    </div>
    <script>        var postfixList = ["163.com", "gmail.com", "126.com", "qq.com", "263.net"];        var txt = document.getElementById("input-email");        var sug = document.getElementById("email-sug-wrapper");
        sug.addEventListener("click",function(ev){            //采用事件代理,监听父级点击事件,通过target获取当前li
            var ev=ev||window.event;            var target=ev.target||ev.srcElement;            if(target.nodeName.toLowerCase()=="li"){
                hide();               return txt.value=htmlDecode( target.innerHTML); //解码
               //return txt.value= target.innerHTML;                          }
            
        })
        txt.oninput = function () {
            console.log("event handle4");
            judge();
            add();

        }        function getText() {            var inputText = txt.value.trim();            return inputText;
        }        //判断是否生成新的数组
        function postlist() {            var userinput = getText();            var newpostlist = new Array();            if (userinput.search('@') != 0) {                var len = userinput.search('@');                //用来拼接的用户输入内容 = 只使用@之后的字符串
                var x = userinput.substring(len + 1, userinput.length); //取@之后的部分
                for (var i = 0; i < postfixList.length; i++) {                    if (postfixList[i].search(x) == 0) {
                        newpostlist.push(postfixList[i]);
                    }
                }                //若@后面没有字符或者新数组newpostlist为空,就返回原来的postfixlist
                if (x === '' || newpostlist == '') {                    return postfixList;
                }                return newpostlist;
            } else {                return postfixList;
            }
        }        //根据输入内容和匹配来生成提示数组
        function promptContent() {            var x = htmlEncode(getText()) //转码;
           // var x=getText();
            var tips = new Array();            if (x.indexOf("@") != -1) {                var p = x.slice(0, x.indexOf("@"));                for (i = 0; i < postlist().length; i++) {
                    tips[i] = p + "@" + postlist()[i];
                }
            } else {                for (i = 0; i < postfixList.length; i++) {
                    tips[i] = x + "@" + postfixList[i];
                }
            }            return tips;
        }        //添加提示数组进入li
        function add() {            var sug = document.getElementById("email-sug-wrapper");            var tips = promptContent();            while (sug.hasChildNodes()) {
                sug.removeChild(sug.firstChild);
            }            //将之前的列表清除掉,然后重新生成新的列表
            for (i = 0; i < tips.length; i++) {                var tip_li = document.createElement("li");
                tip_li.innerHTML = tips[i];
                sug.appendChild(tip_li);
            }
        }        function judge() {            //判空,是“”没有内容,不能为“ ”
            if (getText() == "") {
                hide();
            } else {
                display();
            }

        }        function hide() {
            sug.style.display = "none";
        }        function display() {
            sug.style.display = "block";
        }        /*1.用浏览器内部转换器实现html转码*/
        function htmlEncode(html){            //1.首先动态创建一个容器标签元素,如DIV
            var temp = document.createElement ("div");            //2.然后将要转换的字符串设置为这个元素的innerText(ie支持)或者textContent(火狐,google支持)
            (temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html);            //3.最后返回这个元素的innerHTML,即得到经过HTML编码转换的字符串了
            var output = temp.innerHTML;
            temp = null;            return output;
        }        /*2.用浏览器内部转换器实现html解码*/
        function htmlDecode(text){            //1.首先动态创建一个容器标签元素,如DIV
            var temp = document.createElement("div");            //2.然后将要转换的字符串设置为这个元素的innerHTML(ie,火狐,google都支持)
            temp.innerHTML = text;            //3.最后返回这个元素的innerText(ie支持)或者textContent(火狐,google支持),即得到经过HTML解码的字符串了。
            var output = temp.innerText || temp.textContent;
            temp = null;            return output;
        }    </script>
</body>

</html>

复制代码

加上键盘

需求

我们给提示框加上3个按键的功能,分别是回车和上下键,使得可以通过键盘操作进行提示框的选择

  • 当有提示框的时候,默认第一个提示为被选择状态,用一个和鼠标滑过不一样的背景色来标识

  • 当有输入框的时候,按上键,可以向上移动选择状态,如果按键之前的被选择提示是第一个,则被选状态移到最下面一个

  • 当有输入框的时候,按下键,可以向下移动选择状态,如果按键之前的被选择提示是最后一个,则被选状态移到第一个

  • 当有输入框时,按回车键,则将当前被选中状态的提示内容,放到输入框中,并隐藏提示框

  • 当没有输入框的时候,这3个键盘按键无响应

  • 当用户输入发生改变的时候,选择状态都重新切回到第一个提示

优化体验

需求

当我们进入页面,或者当我们点击鼠标进行提示选择后,输入框的焦点就不在了,所以请你优化一下用户体验:

  • 一进入页面就将焦点放在输入框中

  • 用户点击鼠标,进行提示选择后,焦点依然在输入框中

  • 用户按ESC键的时候,对用户输入进行全选

代码3

复制代码

  1 <!DOCTYPE html>  2 <html>  3   4 <head>  5     <meta charset="utf-8" />  6     <title>邮箱后缀提示3-添加键盘响应及输入框焦点优化</title>  7     <style>  8         #input-email{  9         width: 300px; 10         height: 30px; 11     } 12     .email-sug{ 13         width: 300px; 14         list-style: none; 15         padding: 0px; 16         margin: 0px; 17         border: 2px solid rgba(134, 132, 132,0.3); 18         border-top:none; 19         display: none; 20         /* 初始不显示,避免边框出现 */ 21     } 22     .email-sug li{ 23         width: 300px; 24         height: 30px; 25         background-color: #ffffff; 26         color: darkgrey; 27         line-height: 30px;    
 28         overflow: hidden; 29         padding-left: 10px; 30         box-sizing: border-box; 31     } 32     .email-sug li:hover{ 33         background-color:skyblue; 34     } 35     .email-sug li.active{ 36         background-color:pink; 37     } 38     </style> 39 </head> 40  41 <body> 42     <div class="wrapper"> 43         <input type="text" id="input-email" autofocus="autofocus"> 44         <ul class="email-sug" id="email-sug-wrapper"> 45  46         </ul> 47     </div> 48     <script> 49         var postfixList = ["163.com", "gmail.com", "126.com", "qq.com", "263.net"]; 50         var txt = document.getElementById("input-email"); 51         var sug = document.getElementById("email-sug-wrapper"); 52         var nowSelectTipIndex = 0; 53  54         //获取输入文本 55         txt.oninput = function (e) { 56             console.log("event handle4"); 57             //按下的是内容,则重置选中状态,坐标清零,避免光标位置已经计算存入。 58             if (!(e.keyCode == 40 || e.keyCode == 38 || e.keyCode == 13)) { 59                 nowSelectTipIndex = 0; 60             } 61             judge(); 62             add(); 63         } 64         //点击事件响应 65         sug.addEventListener("click", function (ev) { 66             //采用事件代理,监听父级点击事件,通过target获取当前li 67             var ev = ev || window.event; 68             var target = ev.target || ev.srcElement; 69             if (target.nodeName.toLowerCase() == "li") { 70                 hide(); 71                 txt.focus(); //写在return之前,不然无效 72                 return txt.value = htmlDecode(target.innerHTML); //解码 73                 //return txt.value= target.innerHTML;       74             } 75         }) 76         //键盘事件响应 77         document.addEventListener("keydown", function (e) { 78             var e = e || window.event; 79             var key = e.which || e.keyCode; 80             var list = document.getElementsByTagName("li"); 81             //向下键 82             if (key == 40) { 83                 for (i = 0; i < list.length; i++) { 84                     list[i].setAttribute("class", ""); 85                 } 86                 nowSelectTipIndex++; 87                 if (nowSelectTipIndex + 1 > list.length) { 88                     nowSelectTipIndex = 0; 89                 } 90                 list[nowSelectTipIndex].setAttribute("class", "active"); 91             } 92             //向上键 93             if (key == 38) { 94                 for (i = 0; i < list.length; i++) { 95                     list[i].setAttribute("class", ""); 96                 } 97                 nowSelectTipIndex--; 98                 if (nowSelectTipIndex < 0) { 99                     nowSelectTipIndex = list.length - 1;100                 }101                 list[nowSelectTipIndex].setAttribute("class", "active");102             }103             //回车键104             if (key == 13) {105                 var x = document.getElementsByClassName("active");106                 txt.value = htmlDecode(x[0].innerHTML); //用textcontent会去除html标签例如<b>。。107                 hide();108             }109             if (key == 27) {110                 txt.setSelectionRange(0, -1); //ESC全选上文本框内容111                 hide();112             }113 114         })115         //获取输入内容,并去除首尾空格116         function getText() {117             var inputText = txt.value.trim();118             return inputText;119         }120         //判断是否生成新的数组121         function postlist() {122             var userinput = getText();123             var newpostlist = new Array();124             if (userinput.search('@') != 0) {125                 var len = userinput.search('@');126                 //用来拼接的用户输入内容 = 只使用@之后的字符串127                 var x = userinput.substring(len + 1, userinput.length); //取@之后的部分128                 for (var i = 0; i < postfixList.length; i++) {129                     if (postfixList[i].search(x) == 0) {130                         newpostlist.push(postfixList[i]);131                     }132                 }133                 //若@后面没有字符或者新数组newpostlist为空,就返回原来的postfixlist134                 if (x === '' || newpostlist == '') {135                     return postfixList;136                 }137                 return newpostlist;138             } else {139                 return postfixList;140             }141         }142         //根据输入内容和匹配来生成提示数组143         function promptContent() {144             var x = htmlEncode(getText()); //转码;145             // var x=getText();146             var tips = new Array();147             if (x.indexOf("@") != -1) {148                 var p = x.slice(0, x.indexOf("@"));149                 for (i = 0; i < postlist().length; i++) {150                     tips[i] = p + "@" + postlist()[i];151                 }152             } else {153                 for (i = 0; i < postfixList.length; i++) {154                     tips[i] = x + "@" + postfixList[i];155                 }156             }157             return tips;158         }159         //添加提示数组进入li160         function add() {161             var sug = document.getElementById("email-sug-wrapper");162             var tips = promptContent();163             while (sug.hasChildNodes()) {164                 sug.removeChild(sug.firstChild);165             }166             //将之前的列表清除掉,然后重新生成新的列表167             for (i = 0; i < tips.length; i++) {168                 var tip_li = document.createElement("li");169                 tip_li.innerHTML = tips[i];170                 sug.appendChild(tip_li);171             }172             //初始选择第一项为选中状态,加类名变粉色(需要生成li之后再调用)。173             var list = document.getElementsByTagName("li");174             list[0].setAttribute("class", "active");175         }176 177         function judge() {178             //判空,是“”没有内容,不能为“ ”179             if (getText() == "") {180                 hide();181             } else {182                 display();183             }184 185         }186         //控制提示列表隐藏187         function hide() {188             sug.style.display = "none";189         }190         //控制提示列表显示  191         function display() {192             sug.style.display = "block";193         }194 195         /*1.用浏览器内部转换器实现html转码*/196         function htmlEncode(html) {197             //1.首先动态创建一个容器标签元素,如DIV198             var temp = document.createElement("div");199             //2.然后将要转换的字符串设置为这个元素的innerText(ie支持)或者textContent(火狐,google支持)200             (temp.textContent != undefined) ? (temp.textContent = html) : (temp.innerText = html);201             //3.最后返回这个元素的innerHTML,即得到经过HTML编码转换的字符串了202             var output = temp.innerHTML;203             temp = null;204             return output;205         }206         /*2.用浏览器内部转换器实现html解码*/207         function htmlDecode(text) {208             //1.首先动态创建一个容器标签元素,如DIV209             var temp = document.createElement("div");210             //2.然后将要转换的字符串设置为这个元素的innerHTML(ie,火狐,google都支持)211             temp.innerHTML = text;212             //3.最后返回这个元素的innerText(ie支持)或者textContent(火狐,google支持),即得到经过HTML解码的字符串了。213             var output = temp.innerText || temp.textContent;214             temp = null;215             return output;216         }217     </script>218 </body>219 220 </html>

复制代码

最终效果如图:

原文出处:https://www.cnblogs.com/Joe-and-Joan/p/10111099.html  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消