JavaScript實(shí)現(xiàn)郵箱后綴提示功能的示例代碼
先來個(gè)基礎(chǔ)的
需求
- 根據(jù)下面需求實(shí)現(xiàn)如示意圖所示的郵箱輸入提示功能,注意,根據(jù)要求只需實(shí)現(xiàn)下面功能
- 當(dāng)用戶沒有任何輸入時(shí),提示框消失
- 當(dāng)用戶輸入字符后,顯示提示框,并且把用戶輸入的內(nèi)容自動(dòng)拼上郵箱后綴進(jìn)行顯示
- 暫時(shí)不用考慮示意圖中的紅色和藍(lán)色背景色的邏輯
- 注意用戶輸入中前后空格需要去除
小優(yōu)化編碼
需求
如果我們輸入的是 abc@1,這個(gè)時(shí)候出現(xiàn)的提示框內(nèi)容是
- abc@1@163.com
- abc@1@gmail.com
- abc@1@126.com
- ……
很明顯,上面的提示框不是一個(gè)符合用戶需求的提示,我們需要做一些優(yōu)化:
當(dāng)用戶輸入含有 @ 符號時(shí),我們選取用戶輸入的@前面的字符來和后綴拼接
需求
這下出現(xiàn)的提示好多了,不過用戶如果已經(jīng)輸入了@1,說明他大概率要輸入163或者126,我們需要讓我們的提示更加符合用戶的期望。滿足以下需求:
當(dāng)用戶輸入了 @ 及部分后綴時(shí),只從 postfixList 選取符合用戶輸入預(yù)期的后綴,我們以前綴匹配為要求。
當(dāng)用戶輸入不滿足任何前綴匹配時(shí),則顯示全部提示
測試用例
- 輸入a@1->出現(xiàn)提示框,提示a@163.com, a@126.com
- 輸入a@g->出現(xiàn)提示框,提示a@gmail.com
- 輸入a@2->出現(xiàn)提示框,提示a@263.net
- 輸入a@qq->出現(xiàn)提示框,提示a@qq.com
- 輸入a@163.->出現(xiàn)提示框,提示a@163.com
- 輸入a@126.com->出現(xiàn)提示框,提示a@126.com
- 輸入a@qq.com (兩個(gè)空格)->出現(xiàn)提示框,提示a@qq.com
- 輸入a@qq.comm->出現(xiàn)提示框,出現(xiàn)全部提示 代碼1
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>郵箱后綴提示1-完成基本提示</title> </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"); // keys.addEventListener("keyup",function(){ // console.log("event handle1"); // }) // keys.addEventListener("keypress",function(){ // console.log("event handle2"); // }) // keys.addEventListener("keydown",function(){ // console.log("event handle3"); // }) // keys.addEventListener("input",function(){ // console.log("event handle4"); // }) //經(jīng)過查看各個(gè)效果,oninput效果最符合需求。 txt.oninput = function () { console.log("event handle4"); judge(); add(); } function getText() { var inputText = txt.value.trim(); return inputText; } //判斷是否生成新的數(shù)組 function postlist() { var userinput = getText(); var newpostlist = new Array(); if (userinput.search('@') != 0) { var len = userinput.search('@'); //用來拼接的用戶輸入內(nèi)容 = 只使用@之后的字符串 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]); } } //若@后面沒有字符或者新數(shù)組newpostlist為空,就返回原來的postfixlist if (x === '' || newpostlist == '') { return postfixList; } return newpostlist; } else { return postfixList; } } //根據(jù)輸入內(nèi)容和匹配來生成提示數(shù)組 function promptContent() { 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; } //添加提示數(shù)組進(jìn)入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() { //判空,是“”沒有內(nèi)容,不能為“ ” if (getText() == "") { hide(); } else { display(); } } function hide() { sug.style.display = "none"; } function display() { sug.style.display = "block"; } </script> </body> </html>
新的需求編碼
需求
上面我們只完成了提示,但提示還沒有直接作用到選擇中,我們現(xiàn)在完成以下需求:
- 使用CSS實(shí)現(xiàn):鼠標(biāo)滑過提示框的某一個(gè)提示時(shí),這個(gè)提示內(nèi)容背景色變化,表示鼠標(biāo)經(jīng)過了這個(gè)DOM節(jié)點(diǎn)
- 鼠標(biāo)如果點(diǎn)擊某個(gè)提示,則提示內(nèi)容進(jìn)入輸入框,同時(shí)提示框消失
- 在上個(gè)步驟結(jié)束后,在輸入框中任意再輸入字符或刪除字符,則重新開始出現(xiàn)提示框
需求
嘗試在輸入框中輸入<b>,看看提示框發(fā)生了什么
閱讀
javascript對HTML字符轉(zhuǎn)義與反轉(zhuǎn)義
設(shè)計(jì)
我們需要在兩個(gè)地方進(jìn)行處理,一個(gè)是在生成提示內(nèi)容那里,對于特殊字符進(jìn)行轉(zhuǎn)義編碼,另一個(gè)是在把鼠標(biāo)點(diǎn)擊的提示框內(nèi)容轉(zhuǎn)回輸入框時(shí)進(jìn)行解碼。
代碼2
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>郵箱后綴提示2-添加樣式和監(jiān)聽鼠標(biāo)點(diǎn)擊和轉(zhuǎn)碼內(nèi)容</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; /* 初始不顯示,避免邊框出現(xiàn) */ } .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){ //采用事件代理,監(jiān)聽父級點(diǎn)擊事件,通過target獲取當(dāng)前l(fā)i 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; } //判斷是否生成新的數(shù)組 function postlist() { var userinput = getText(); var newpostlist = new Array(); if (userinput.search('@') != 0) { var len = userinput.search('@'); //用來拼接的用戶輸入內(nèi)容 = 只使用@之后的字符串 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]); } } //若@后面沒有字符或者新數(shù)組newpostlist為空,就返回原來的postfixlist if (x === '' || newpostlist == '') { return postfixList; } return newpostlist; } else { return postfixList; } } //根據(jù)輸入內(nèi)容和匹配來生成提示數(shù)組 function promptContent() { var x = htmlEncode(getText()) //轉(zhuǎn)碼; // 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; } //添加提示數(shù)組進(jìn)入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() { //判空,是“”沒有內(nèi)容,不能為“ ” if (getText() == "") { hide(); } else { display(); } } function hide() { sug.style.display = "none"; } function display() { sug.style.display = "block"; } /*1.用瀏覽器內(nèi)部轉(zhuǎn)換器實(shí)現(xiàn)html轉(zhuǎn)碼*/ function htmlEncode(html){ //1.首先動(dòng)態(tài)創(chuàng)建一個(gè)容器標(biāo)簽元素,如DIV var temp = document.createElement ("div"); //2.然后將要轉(zhuǎn)換的字符串設(shè)置為這個(gè)元素的innerText(ie支持)或者textContent(火狐,google支持) (temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html); //3.最后返回這個(gè)元素的innerHTML,即得到經(jīng)過HTML編碼轉(zhuǎn)換的字符串了 var output = temp.innerHTML; temp = null; return output; } /*2.用瀏覽器內(nèi)部轉(zhuǎn)換器實(shí)現(xiàn)html解碼*/ function htmlDecode(text){ //1.首先動(dòng)態(tài)創(chuàng)建一個(gè)容器標(biāo)簽元素,如DIV var temp = document.createElement("div"); //2.然后將要轉(zhuǎn)換的字符串設(shè)置為這個(gè)元素的innerHTML(ie,火狐,google都支持) temp.innerHTML = text; //3.最后返回這個(gè)元素的innerText(ie支持)或者textContent(火狐,google支持),即得到經(jīng)過HTML解碼的字符串了。 var output = temp.innerText || temp.textContent; temp = null; return output; } </script> </body> </html>
加上鍵盤
需求
我們給提示框加上3個(gè)按鍵的功能,分別是回車和上下鍵,使得可以通過鍵盤操作進(jìn)行提示框的選擇
- 當(dāng)有提示框的時(shí)候,默認(rèn)第一個(gè)提示為被選擇狀態(tài),用一個(gè)和鼠標(biāo)滑過不一樣的背景色來標(biāo)識
- 當(dāng)有輸入框的時(shí)候,按上鍵,可以向上移動(dòng)選擇狀態(tài),如果按鍵之前的被選擇提示是第一個(gè),則被選狀態(tài)移到最下面一個(gè)
- 當(dāng)有輸入框的時(shí)候,按下鍵,可以向下移動(dòng)選擇狀態(tài),如果按鍵之前的被選擇提示是最后一個(gè),則被選狀態(tài)移到第一個(gè)
- 當(dāng)有輸入框時(shí),按回車鍵,則將當(dāng)前被選中狀態(tài)的提示內(nèi)容,放到輸入框中,并隱藏提示框
- 當(dāng)沒有輸入框的時(shí)候,這3個(gè)鍵盤按鍵無響應(yīng)
- 當(dāng)用戶輸入發(fā)生改變的時(shí)候,選擇狀態(tài)都重新切回到第一個(gè)提示
優(yōu)化體驗(yàn)
需求
當(dāng)我們進(jìn)入頁面,或者當(dāng)我們點(diǎn)擊鼠標(biāo)進(jìn)行提示選擇后,輸入框的焦點(diǎn)就不在了,所以請你優(yōu)化一下用戶體驗(yàn):
一進(jìn)入頁面就將焦點(diǎn)放在輸入框中
用戶點(diǎn)擊鼠標(biāo),進(jìn)行提示選擇后,焦點(diǎn)依然在輸入框中
用戶按ESC鍵的時(shí)候,對用戶輸入進(jìn)行全選
代碼3
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>郵箱后綴提示3-添加鍵盤響應(yīng)及輸入框焦點(diǎn)優(yōu)化</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; /* 初始不顯示,避免邊框出現(xiàn) */ } .email-sug li{ width: 300px; height: 30px; background-color: #ffffff; color: darkgrey; line-height: 30px; overflow: hidden; padding-left: 10px; box-sizing: border-box; } .email-sug li:hover{ background-color:skyblue; } .email-sug li.active{ background-color:pink; } </style> </head> <body> <div class="wrapper"> <input type="text" id="input-email" autofocus="autofocus"> <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"); var nowSelectTipIndex = 0; //獲取輸入文本 txt.oninput = function (e) { console.log("event handle4"); //按下的是內(nèi)容,則重置選中狀態(tài),坐標(biāo)清零,避免光標(biāo)位置已經(jīng)計(jì)算存入。 if (!(e.keyCode == 40 || e.keyCode == 38 || e.keyCode == 13)) { nowSelectTipIndex = 0; } judge(); add(); } //點(diǎn)擊事件響應(yīng) sug.addEventListener("click", function (ev) { //采用事件代理,監(jiān)聽父級點(diǎn)擊事件,通過target獲取當(dāng)前l(fā)i var ev = ev || window.event; var target = ev.target || ev.srcElement; if (target.nodeName.toLowerCase() == "li") { hide(); txt.focus(); //寫在return之前,不然無效 return txt.value = htmlDecode(target.innerHTML); //解碼 //return txt.value= target.innerHTML; } }) //鍵盤事件響應(yīng) document.addEventListener("keydown", function (e) { var e = e || window.event; var key = e.which || e.keyCode; var list = document.getElementsByTagName("li"); //向下鍵 if (key == 40) { for (i = 0; i < list.length; i++) { list[i].setAttribute("class", ""); } nowSelectTipIndex++; if (nowSelectTipIndex + 1 > list.length) { nowSelectTipIndex = 0; } list[nowSelectTipIndex].setAttribute("class", "active"); } //向上鍵 if (key == 38) { for (i = 0; i < list.length; i++) { list[i].setAttribute("class", ""); } nowSelectTipIndex--; if (nowSelectTipIndex < 0) { nowSelectTipIndex = list.length - 1; } list[nowSelectTipIndex].setAttribute("class", "active"); } //回車鍵 if (key == 13) { var x = document.getElementsByClassName("active"); txt.value = htmlDecode(x[0].innerHTML); //用textcontent會去除html標(biāo)簽例如<b>。。 hide(); } if (key == 27) { txt.setSelectionRange(0, -1); //ESC全選上文本框內(nèi)容 hide(); } }) //獲取輸入內(nèi)容,并去除首尾空格 function getText() { var inputText = txt.value.trim(); return inputText; } //判斷是否生成新的數(shù)組 function postlist() { var userinput = getText(); var newpostlist = new Array(); if (userinput.search('@') != 0) { var len = userinput.search('@'); //用來拼接的用戶輸入內(nèi)容 = 只使用@之后的字符串 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]); } } //若@后面沒有字符或者新數(shù)組newpostlist為空,就返回原來的postfixlist if (x === '' || newpostlist == '') { return postfixList; } return newpostlist; } else { return postfixList; } } //根據(jù)輸入內(nèi)容和匹配來生成提示數(shù)組 function promptContent() { var x = htmlEncode(getText()); //轉(zhuǎn)碼; // 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; } //添加提示數(shù)組進(jìn)入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); } //初始選擇第一項(xiàng)為選中狀態(tài),加類名變粉色(需要生成li之后再調(diào)用)。 var list = document.getElementsByTagName("li"); list[0].setAttribute("class", "active"); } function judge() { //判空,是“”沒有內(nèi)容,不能為“ ” if (getText() == "") { hide(); } else { display(); } } //控制提示列表隱藏 function hide() { sug.style.display = "none"; } //控制提示列表顯示 function display() { sug.style.display = "block"; } /*1.用瀏覽器內(nèi)部轉(zhuǎn)換器實(shí)現(xiàn)html轉(zhuǎn)碼*/ function htmlEncode(html) { //1.首先動(dòng)態(tài)創(chuàng)建一個(gè)容器標(biāo)簽元素,如DIV var temp = document.createElement("div"); //2.然后將要轉(zhuǎn)換的字符串設(shè)置為這個(gè)元素的innerText(ie支持)或者textContent(火狐,google支持) (temp.textContent != undefined) ? (temp.textContent = html) : (temp.innerText = html); //3.最后返回這個(gè)元素的innerHTML,即得到經(jīng)過HTML編碼轉(zhuǎn)換的字符串了 var output = temp.innerHTML; temp = null; return output; } /*2.用瀏覽器內(nèi)部轉(zhuǎn)換器實(shí)現(xiàn)html解碼*/ function htmlDecode(text) { //1.首先動(dòng)態(tài)創(chuàng)建一個(gè)容器標(biāo)簽元素,如DIV var temp = document.createElement("div"); //2.然后將要轉(zhuǎn)換的字符串設(shè)置為這個(gè)元素的innerHTML(ie,火狐,google都支持) temp.innerHTML = text; //3.最后返回這個(gè)元素的innerText(ie支持)或者textContent(火狐,google支持),即得到經(jīng)過HTML解碼的字符串了。 var output = temp.innerText || temp.textContent; temp = null; return output; } </script> </body> </html>
最終效果如圖:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Javascript數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列詳解
要了解JavaScript數(shù)組的堆棧和隊(duì)列方法的操作,需要先對堆棧和隊(duì)列基礎(chǔ)知識有所了解,下面這篇文章主要給大家介紹了關(guān)于Javascript數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05javascript 上下banner替換具體實(shí)現(xiàn)
這篇文章介紹了javascript 上下banner替換具體實(shí)現(xiàn),有需要的朋友可以參考一下2013-11-11javascript 翻頁測試頁(動(dòng)態(tài)創(chuàng)建標(biāo)簽并自動(dòng)翻頁)
javascript 翻頁測試頁(動(dòng)態(tài)創(chuàng)建標(biāo)簽并自動(dòng)翻頁),需要的朋友可以參考下。2009-12-12javascript實(shí)現(xiàn)保留兩位小數(shù)的多種方法
這篇文章主要介紹了javascript實(shí)現(xiàn)保留兩位小數(shù)的多種方法,如果數(shù)字的原本小數(shù)位數(shù)不到兩位,那么缺少的就自動(dòng)補(bǔ)零,感興趣的小伙伴們可以參考一下2015-12-12獲取css樣式表內(nèi)樣式的js函數(shù)currentStyle(IE),defaultView(FF)
JS從樣式表取值的函數(shù),IE中以currentStyle,firefox中defaultView來獲取,需要的朋友可以參考下。2011-02-02JavaScript中高階函數(shù)的巧妙運(yùn)用
JavaScript中的高階函數(shù)是指可以接受其他函數(shù)作為參數(shù)或者返回一個(gè)函數(shù)作為結(jié)果的函數(shù),本文介紹了JS中一些高階函數(shù)的妙用,希望對大家有所幫助2023-05-05