JavaScript實現(xiàn)郵箱后綴提示功能的示例代碼
先來個基礎的
需求
- 根據(jù)下面需求實現(xiàn)如示意圖所示的郵箱輸入提示功能,注意,根據(jù)要求只需實現(xiàn)下面功能
- 當用戶沒有任何輸入時,提示框消失
- 當用戶輸入字符后,顯示提示框,并且把用戶輸入的內(nèi)容自動拼上郵箱后綴進行顯示
- 暫時不用考慮示意圖中的紅色和藍色背景色的邏輯
- 注意用戶輸入中前后空格需要去除
小優(yōu)化編碼
需求
如果我們輸入的是 abc@1,這個時候出現(xiàn)的提示框內(nèi)容是
- abc@1@163.com
- abc@1@gmail.com
- abc@1@126.com
- ……
很明顯,上面的提示框不是一個符合用戶需求的提示,我們需要做一些優(yōu)化:
當用戶輸入含有 @ 符號時,我們選取用戶輸入的@前面的字符來和后綴拼接
需求
這下出現(xiàn)的提示好多了,不過用戶如果已經(jīng)輸入了@1,說明他大概率要輸入163或者126,我們需要讓我們的提示更加符合用戶的期望。滿足以下需求:
當用戶輸入了 @ 及部分后綴時,只從 postfixList 選取符合用戶輸入預期的后綴,我們以前綴匹配為要求。
當用戶輸入不滿足任何前綴匹配時,則顯示全部提示
測試用例
- 輸入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 (兩個空格)->出現(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)過查看各個效果,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ù)組進入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實現(xiàn):鼠標滑過提示框的某一個提示時,這個提示內(nèi)容背景色變化,表示鼠標經(jīng)過了這個DOM節(jié)點
- 鼠標如果點擊某個提示,則提示內(nèi)容進入輸入框,同時提示框消失
- 在上個步驟結束后,在輸入框中任意再輸入字符或刪除字符,則重新開始出現(xiàn)提示框
需求
嘗試在輸入框中輸入<b>,看看提示框發(fā)生了什么
閱讀
javascript對HTML字符轉(zhuǎn)義與反轉(zhuǎn)義
設計
我們需要在兩個地方進行處理,一個是在生成提示內(nèi)容那里,對于特殊字符進行轉(zhuǎn)義編碼,另一個是在把鼠標點擊的提示框內(nèi)容轉(zhuǎn)回輸入框時進行解碼。
代碼2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>郵箱后綴提示2-添加樣式和監(jiā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)聽父級點擊事件,通過target獲取當前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ù)組進入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)換器實現(xiàn)html轉(zhuǎn)碼*/
function htmlEncode(html){
//1.首先動態(tài)創(chuàng)建一個容器標簽元素,如DIV
var temp = document.createElement ("div");
//2.然后將要轉(zhuǎn)換的字符串設置為這個元素的innerText(ie支持)或者textContent(火狐,google支持)
(temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html);
//3.最后返回這個元素的innerHTML,即得到經(jīng)過HTML編碼轉(zhuǎn)換的字符串了
var output = temp.innerHTML;
temp = null;
return output;
}
/*2.用瀏覽器內(nèi)部轉(zhuǎn)換器實現(xiàn)html解碼*/
function htmlDecode(text){
//1.首先動態(tài)創(chuàng)建一個容器標簽元素,如DIV
var temp = document.createElement("div");
//2.然后將要轉(zhuǎn)換的字符串設置為這個元素的innerHTML(ie,火狐,google都支持)
temp.innerHTML = text;
//3.最后返回這個元素的innerText(ie支持)或者textContent(火狐,google支持),即得到經(jīng)過HTML解碼的字符串了。
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
</script>
</body>
</html>
加上鍵盤
需求
我們給提示框加上3個按鍵的功能,分別是回車和上下鍵,使得可以通過鍵盤操作進行提示框的選擇
- 當有提示框的時候,默認第一個提示為被選擇狀態(tài),用一個和鼠標滑過不一樣的背景色來標識
- 當有輸入框的時候,按上鍵,可以向上移動選擇狀態(tài),如果按鍵之前的被選擇提示是第一個,則被選狀態(tài)移到最下面一個
- 當有輸入框的時候,按下鍵,可以向下移動選擇狀態(tài),如果按鍵之前的被選擇提示是最后一個,則被選狀態(tài)移到第一個
- 當有輸入框時,按回車鍵,則將當前被選中狀態(tài)的提示內(nèi)容,放到輸入框中,并隱藏提示框
- 當沒有輸入框的時候,這3個鍵盤按鍵無響應
- 當用戶輸入發(fā)生改變的時候,選擇狀態(tài)都重新切回到第一個提示
優(yōu)化體驗
需求
當我們進入頁面,或者當我們點擊鼠標進行提示選擇后,輸入框的焦點就不在了,所以請你優(yōu)化一下用戶體驗:
一進入頁面就將焦點放在輸入框中
用戶點擊鼠標,進行提示選擇后,焦點依然在輸入框中
用戶按ESC鍵的時候,對用戶輸入進行全選
代碼3
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>郵箱后綴提示3-添加鍵盤響應及輸入框焦點優(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),坐標清零,避免光標位置已經(jīng)計算存入。
if (!(e.keyCode == 40 || e.keyCode == 38 || e.keyCode == 13)) {
nowSelectTipIndex = 0;
}
judge();
add();
}
//點擊事件響應
sug.addEventListener("click", function (ev) {
//采用事件代理,監(jiān)聽父級點擊事件,通過target獲取當前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;
}
})
//鍵盤事件響應
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標簽例如<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ù)組進入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);
}
//初始選擇第一項為選中狀態(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)換器實現(xiàn)html轉(zhuǎn)碼*/
function htmlEncode(html) {
//1.首先動態(tài)創(chuàng)建一個容器標簽元素,如DIV
var temp = document.createElement("div");
//2.然后將要轉(zhuǎn)換的字符串設置為這個元素的innerText(ie支持)或者textContent(火狐,google支持)
(temp.textContent != undefined) ? (temp.textContent = html) : (temp.innerText = html);
//3.最后返回這個元素的innerHTML,即得到經(jīng)過HTML編碼轉(zhuǎn)換的字符串了
var output = temp.innerHTML;
temp = null;
return output;
}
/*2.用瀏覽器內(nèi)部轉(zhuǎn)換器實現(xiàn)html解碼*/
function htmlDecode(text) {
//1.首先動態(tài)創(chuàng)建一個容器標簽元素,如DIV
var temp = document.createElement("div");
//2.然后將要轉(zhuǎn)換的字符串設置為這個元素的innerHTML(ie,火狐,google都支持)
temp.innerHTML = text;
//3.最后返回這個元素的innerText(ie支持)或者textContent(火狐,google支持),即得到經(jīng)過HTML解碼的字符串了。
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
</script>
</body>
</html>
最終效果如圖:



以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Javascript數(shù)據(jù)結構之棧和隊列詳解
要了解JavaScript數(shù)組的堆棧和隊列方法的操作,需要先對堆棧和隊列基礎知識有所了解,下面這篇文章主要給大家介紹了關于Javascript數(shù)據(jù)結構之棧和隊列的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-05-05
javascript 上下banner替換具體實現(xiàn)
這篇文章介紹了javascript 上下banner替換具體實現(xiàn),有需要的朋友可以參考一下2013-11-11
javascript 翻頁測試頁(動態(tài)創(chuàng)建標簽并自動翻頁)
javascript 翻頁測試頁(動態(tài)創(chuàng)建標簽并自動翻頁),需要的朋友可以參考下。2009-12-12
javascript實現(xiàn)保留兩位小數(shù)的多種方法
這篇文章主要介紹了javascript實現(xiàn)保留兩位小數(shù)的多種方法,如果數(shù)字的原本小數(shù)位數(shù)不到兩位,那么缺少的就自動補零,感興趣的小伙伴們可以參考一下2015-12-12
獲取css樣式表內(nèi)樣式的js函數(shù)currentStyle(IE),defaultView(FF)
JS從樣式表取值的函數(shù),IE中以currentStyle,firefox中defaultView來獲取,需要的朋友可以參考下。2011-02-02

