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

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset=“utf-8” />
  6. <title>邮箱后缀提示2-添加样式和监听鼠标点击和转码内容</title>
  7. <style>
  8. #input-email{
  9. width: 300px;
  10. height: 30px;
  11. }
  12. .emailsug{
  13. width: 300px;
  14. liststyle: none;
  15. padding: 0px;
  16. margin: 0px;
  17. border: 2px solid rgba(134, 132, 132,0.3);
  18. bordertop:none;
  19. display: none;
  20. /* 初始不显示,避免边框出现 */
  21. }
  22. .emailsug li{
  23. width: 300px;
  24. height: 30px;
  25. backgroundcolor: #ffffff;
  26. color: darkgrey;
  27. lineheight: 30px;
  28. }
  29. .emailsug li:hover{
  30. backgroundcolor:pink;
  31. }
  32. </style>
  33. </head>
  34.  
  35. <body>
  36. <div class=“wrapper”>
  37. <input type=“text” id=“input-email”>
  38. <ul class=“email-sug” id=“email-sug-wrapper”>
  39.  
  40. </ul>
  41. </div>
  42. <script>
  43. var postfixList = [“163.com”, “gmail.com”, “126.com”, “qq.com”, “263.net”];
  44. var txt = document.getElementById(“input-email”);
  45. var sug = document.getElementById(“email-sug-wrapper”);
  46. sug.addEventListener(“click”,function(ev){
  47. //采用事件代理,监听父级点击事件,通过target获取当前li
  48. var ev=ev||window.event;
  49. var target=ev.target||ev.srcElement;
  50. if(target.nodeName.toLowerCase()==“li”){
  51. hide();
  52. return txt.value=htmlDecode( target.innerHTML); //解码
  53. //return txt.value= target.innerHTML;
  54. }
  55.  
  56. })
  57. txt.oninput = function () {
  58. console.log(“event handle4”);
  59. judge();
  60. add();
  61.  
  62. }
  63.  
  64. function getText() {
  65. var inputText = txt.value.trim();
  66. return inputText;
  67. }
  68. //判断是否生成新的数组
  69. function postlist() {
  70. var userinput = getText();
  71. var newpostlist = new Array();
  72. if (userinput.search(‘@’) != 0) {
  73. var len = userinput.search(‘@’);
  74. //用来拼接的用户输入内容 = 只使用@之后的字符串
  75. var x = userinput.substring(len + 1, userinput.length); //取@之后的部分
  76. for (var i = 0; i < postfixList.length; i++) {
  77. if (postfixList[i].search(x) == 0) {
  78. newpostlist.push(postfixList[i]);
  79. }
  80. }
  81. //若@后面没有字符或者新数组newpostlist为空,就返回原来的postfixlist
  82. if (x === || newpostlist == ) {
  83. return postfixList;
  84. }
  85. return newpostlist;
  86. } else {
  87. return postfixList;
  88. }
  89. }
  90. //根据输入内容和匹配来生成提示数组
  91. function promptContent() {
  92. var x = htmlEncode(getText()) //转码;
  93. // var x=getText();
  94. var tips = new Array();
  95. if (x.indexOf(“@”) != 1) {
  96. var p = x.slice(0, x.indexOf(“@”));
  97. for (i = 0; i < postlist().length; i++) {
  98. tips[i] = p + “@” + postlist()[i];
  99. }
  100. } else {
  101. for (i = 0; i < postfixList.length; i++) {
  102. tips[i] = x + “@” + postfixList[i];
  103. }
  104. }
  105. return tips;
  106. }
  107. //添加提示数组进入li
  108. function add() {
  109. var sug = document.getElementById(“email-sug-wrapper”);
  110. var tips = promptContent();
  111. while (sug.hasChildNodes()) {
  112. sug.removeChild(sug.firstChild);
  113. }
  114. //将之前的列表清除掉,然后重新生成新的列表
  115. for (i = 0; i < tips.length; i++) {
  116. var tip_li = document.createElement(“li”);
  117. tip_li.innerHTML = tips[i];
  118. sug.appendChild(tip_li);
  119. }
  120. }
  121.  
  122. function judge() {
  123. //判空,是“”没有内容,不能为“ ”
  124. if (getText() == “”) {
  125. hide();
  126. } else {
  127. display();
  128. }
  129.  
  130. }
  131.  
  132. function hide() {
  133. sug.style.display = “none”;
  134. }
  135.  
  136. function display() {
  137. sug.style.display = “block”;
  138. }
  139.  
  140. /*1.用浏览器内部转换器实现html转码*/
  141. function htmlEncode(html){
  142. //1.首先动态创建一个容器标签元素,如DIV
  143. var temp = document.createElement (“div”);
  144. //2.然后将要转换的字符串设置为这个元素的innerText(ie支持)或者textContent(火狐,google支持)
  145. (temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html);
  146. //3.最后返回这个元素的innerHTML,即得到经过HTML编码转换的字符串了
  147. var output = temp.innerHTML;
  148. temp = null;
  149. return output;
  150. }
  151. /*2.用浏览器内部转换器实现html解码*/
  152. function htmlDecode(text){
  153. //1.首先动态创建一个容器标签元素,如DIV
  154. var temp = document.createElement(“div”);
  155. //2.然后将要转换的字符串设置为这个元素的innerHTML(ie,火狐,google都支持)
  156. temp.innerHTML = text;
  157. //3.最后返回这个元素的innerText(ie支持)或者textContent(火狐,google支持),即得到经过HTML解码的字符串了。
  158. var output = temp.innerText || temp.textContent;
  159. temp = null;
  160. return output;
  161. }
  162. </script>
  163. </body>
  164.  
  165. </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. .emailsug{
  13. width: 300px;
  14. liststyle: none;
  15. padding: 0px;
  16. margin: 0px;
  17. border: 2px solid rgba(134, 132, 132,0.3);
  18. bordertop:none;
  19. display: none;
  20. /* 初始不显示,避免边框出现 */
  21. }
  22. .emailsug li{
  23. width: 300px;
  24. height: 30px;
  25. backgroundcolor: #ffffff;
  26. color: darkgrey;
  27. lineheight: 30px;
  28. overflow: hidden;
  29. paddingleft: 10px;
  30. boxsizing: borderbox;
  31. }
  32. .emailsug li:hover{
  33. backgroundcolor:skyblue;
  34. }
  35. .emailsug li.active{
  36. backgroundcolor: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>

最终效果如图:

JavaScript实现邮箱后缀提示功能

JavaScript实现邮箱后缀提示功能

JavaScript实现邮箱后缀提示功能

微信公众号:rizhuti
关注我们,获取更多的全网素材资源,有趣有料!
12000人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏