先来个基础的

需求

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

  • 当用户没有任何输入时,提示框消失
  • 当用户输入字符后,显示提示框,并且把用户输入的内容自动拼上邮箱后缀进行显示
  • 暂时不用考虑示意图中的红色和蓝色背景色的逻辑
  • 注意用户输入中前后空格需要去除

小优化编码

需求

如果我们输入的是 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>,看看提示框发生了什么

阅读

  • Web安全之XSS攻防
  • javascript对HTML字符转义与反转义

设计

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

代码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获取当前livar 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为空,就返回原来的postfixlistif (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;}//添加提示数组进入lifunction 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.首先动态创建一个容器标签元素,如DIVvar 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.首先动态创建一个容器标签元素,如DIVvar 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为空,就返回原来的postfixlist
134                 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         //添加提示数组进入li
160         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.首先动态创建一个容器标签元素,如DIV
198             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.首先动态创建一个容器标签元素,如DIV
209             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

JavaScript实现邮箱后缀提示功能相关推荐

  1. [模仿微软Live.cn]JavaScript输入邮箱自动提示

    原理是:在一个输入框 中,当我输入任何字的时候 自动下拉相应的邮箱提示,在输入框输入123的时候 下拉框有所有123的邮箱 输入其他的时候 有其他文案对应的邮箱. 同理 此插件不需要任何html标签, ...

  2. iOS邮箱模糊匹配功能集成

    大家有些人应该遇到产品汪提过这样的需求,产品汪说:"某某App的订单填写页,输入用户邮箱有个提示邮箱后缀的功能,很好用啊!还可以根据各个邮箱类型用户量来做一个优先级的匹配哦.你可以不可以帮我 ...

  3. VS 2008的JavaScript代码提示功能 (学习老赵视频的笔记)

    学习老赵的视频ASP.NET AJAX深入浅出系列课程(19):VS 2008的JavaScript代码提示功能(Level 200) 自己做的demo,记下来以便查阅!感谢赵老师! 原来js还可以像 ...

  4. 输入邮箱时自动提示邮箱后缀

    如题所示: 在html中输入邮箱的input要有自己的class,以及自己父元素的class.例如: <div class="parentemail"><inpu ...

  5. Eclips写Java代码和CSS、Javascript、Html代码设置代码自动提示功能

    按照我的方法设置后用Eclipse编写Java代码和前端代码(Html.CSS.JS)都可以自动提示代码.赶紧去试试吧. 1.打开Eclipse软件,点击Windows→Preferences→Jav ...

  6. php 智能输入提示插件,phph 输入邮箱时自动提示邮箱后缀 实现代码

    1.在html中输入邮箱的input要有自己的class,以及自己父元素的class.例如: // 初始化 $(function() { new EmailAutoComplete({ parentC ...

  7. jquery仿邮箱文本输入框自动加载邮箱后缀

    jquery仿邮箱文本输入框自动加载邮箱后缀 在像百度这样的网站注册时,你会看到输入邮箱会出现自动给用户输入补全主流邮箱.这种对于增加用户体验的小例子已司空见惯.正好看到人家写的这种js功能.还挺不错 ...

  8. jQuery插件AjaxFileUpload文件上传实现Javascript多文件上传功能

     Ajax file upload plugin是一个功能强大的文件上传jQuery插件,可自定义链接.或其它元素庖代传统的file表单上传结果,可实现Ajax动态提示文件上传 过程,同时支撑多文 ...

  9. html中搜索框提示语,JS实现搜索关键词的智能提示功能

    最近在百度搜索的时候,当你输入一个字或者词的时候,他会给你们弹出一个下拉框出来,里面是和你相关的搜索提示 比如 我输入杨字,他会给我提示以下搜索提示 我尝试着用JavaScript做了一个类似的练习, ...

  10. 站长工具|百度搜索框提示功能

    百度向站长开放免费"百度搜索框"代码和"百度搜索框提示"代码.只需进行简单的设置, 即可将" 百度搜索框( 带提示功能)"功能快速加入到您的 ...

最新文章

  1. 【jqgrid】疑难杂症及解决方法(随缘更新)
  2. 疯狂的程序员_程序员的乐趣是什么?
  3. 如果能够让出资人了解更多的c++项目进程
  4. Python相关的考试和认证
  5. 实训项目四 powerpoint 综合应用_【深化改革结硕果】新疆番茄综合精深加工关键技术及产业化应用项目取得重大突破...
  6. Spark--安装和配置遇到的所有问题
  7. UML 结构图之包图 总结
  8. 华为手机网络连接不可用怎么解决_和平精英卡顿怎么解决?玩手机游戏用什么加速器比较好?...
  9. RS232串口接线图
  10. 跳槽理由—你的跳槽理由合理吗
  11. 16张扑克逻辑思维问题详解
  12. 压力测试 闪存_[实验]苹果今年大范围使用的TLC闪存颗粒真的是那么不堪吗?
  13. 让整个页面从iframe中跳出来
  14. Android合理的使用闪屏
  15. OpenCV2.4.13 文本分割(水平垂直,直方图投影)
  16. c语言实现rsa签名验证,C语言openssl库RSA签名
  17. Ubuntu 登录界面键盘鼠标失效的解决方案
  18. vue 省市区选择插件v-distpicker设置初值与选择后触发方法
  19. unicode汉字内码表(转)
  20. 循环渐进NsDoor(五)

热门文章

  1. 【邮箱】Foxmail中如何登陆网易邮箱?
  2. 产品流程、开发流程、测试流程、运维流程、售前流程改进建议
  3. 小程序源代码 古诗词
  4. 计算机课程总结800字,计算机课程心得体会范文800字(通用5篇)
  5. 快速原型工具,帮你从0开始画原型图!
  6. HttpStatus详解
  7. # 2021-03-04 文件搜索命令 find
  8. 使用Elasticsearch搭建一个文件搜索系统(带界面)
  9. U3D记腾讯面试经历
  10. 如何准备全国计算机二级Python,二级Python考试技巧