小练习4:输入提示框
任务描述
在和上一任务同一目录下面创建一个task0002_4.html
文件,在js
目录中创建task0002_4.js
,并在其中编码,实现一个类似百度搜索框的输入提示的功能。
要求如下:
- 允许使用鼠标点击选中提示栏中的某个选项
- 允许使用键盘上下键来选中提示栏中的某个选项,回车确认选中
- 选中后,提示内容变更到输入框中
初级班:
- 不要求和后端交互,可以自己伪造一份提示数据例如:
var suggestData = ['Simon', 'Erik', 'Kener'];
自己搭建一个后端Server,使用Ajax来获取提示数据中级班:
示例:
思路
先拆分步骤进行。
简单分析下实现这个功能应有什么步骤了?
- 允许使用鼠标点击选中提示栏中的某个选项(鼠标点击)
- 允许使用键盘上下键来选中提示栏中的某个选项,回车确认选中(键盘事件)
- 选中后,提示内容变更到输入框中(?)
初步设想有“chick”,"keydown";
当然鼠标移入移出事件也是应该加入的“mouseover”,“mouseleave”;
- 选中后,提示内容变更到输入框中(?)
谷歌了下监视输入框的值变化可以用:“标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化”
参考文章:http://www.cnblogs.com/lhb25/archive/2012/11/30/oninput-and-onpropertychange-event-for-input.html
选中提示:在选定元素上添加选中的样式就可以了;
(1)首先先在html设置好“li”的内容
点击输入框在下面弹出“li”列表;
先为input绑定“chick”事件,单击就显示列表;先不考虑什么时候隐藏列表;
然后鼠标移入列表(一开始打算是通过js来改变样式,后来试了下用hover也可以,更方便),点击之后添加内容到输入框里面(innerHtml),然后列表就设置自动隐藏了(display:none);
既然是每个li的话都有可能发生事件的话,那么就采用事件代理对每个“li”进行绑定事件(addEventListener)。
(2)对键盘事件进行判断
当点击输入框时候(我在代码里改为了“focus”事件);
按下键盘“下”键,这时候判断下“li”列表没有没被选中,
1、如果有,获取此时是选中样式“active”的元素,该元素去除“active”样式,下一个兄弟元素添加选中样式“active”;(这里选取下一个兄弟元素用"nextElementSibling"方法进行选取);
2、如果无,那就将第一个“li”设置为“active”;
3、同理按键盘“上”键也是一样;不过这里就用previousElementSibling方法;
4、按下确定键,处理的方法与鼠标点击类似;获取并添加当前内容;
5、这里做了点小的用户体验优化,等按上下键按到列表的最顶或者最底,弹出提示信息告知用户;同时也免得浏览器报错啊。
(3)提示内容变更到输入框中
上面说到用“input ”事件,监听输入框里面的数据;
首先清除掉之前设置的“li”;
当输入框里面的数据进行变更的时候,与提示数据textdate进行对比;
这里用了array.filter和.match方法;得到符合的数组元素后,在一个个进行输出就好了。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title></title> <style> ul,li{ padding: 0; margin: 0; list-style-type: none; } li{ background-color: #f4f4f4; } .list{ 184px; } .text{ 180px; } .date{ display: none; } .date li:hover{ background-color: #1f8af1; color: #fff } .active{ background-color: #1f8af1; color: #fff } </style> </head> <body> <p>test</p> <div class="list"> <input type="text" class="text"> <ul class="date"> </ul> </div> </body> <script> var testdate=["abase","abash","abate","abduction","abhor","abominable","abscond","abstain","baby","babysiter","belt","birthday","bench","brave","你好"]; var text=document.getElementsByClassName("text")[0]; var oUl=document.getElementsByClassName("date")[0]; var oLi=document.querySelectorAll(".date li"); text.addEventListener("focus",function(e){//文本框点击事件 if(text.value=""){ oUl.innerHTML=""; } else{ document.onkeydown = function (e) { if(e.keyCode==40){ var actli=document.querySelector(".active"); if(actli){ if(actli.nextElementSibling==null){ alert("已经是最底了"); return false; } actli.nextElementSibling.className="active"; actli.className=""; } else{ var oLi=document.querySelectorAll(".date li"); oLi[0].className="active"; } }; if(e.keyCode==38){ var actli=document.querySelector(".active"); if(actli){ if(actli.previousElementSibling==null){ alert("已经是最顶了") return false; } actli.previousElementSibling.className="active"; actli.className=""; } } if(e.keyCode==13){ var actli=document.querySelector(".active"); var val=actli.innerText; text.value=val; actli.className=""; oUl.style.display="none"; } }//下拉栏键盘事件 } }); oUl.addEventListener("mouseover",function(e){//下拉栏鼠标移入事件 var actli=document.querySelector(".active"); if(actli){ actli.className=""; } }); oUl.addEventListener("mouseleave",function(e){//下拉栏鼠标移出事件 oUl.style.display="none"; oUl.innerHTML="" }); oUl.addEventListener("click",function(e){//下拉栏鼠标点击事件 var val=event.target.innerText; text.value=val; oUl.style.display="none"; }); text.oninput=check;//监听input的值 function check(){ var input=text.value; if(input===""){ oUl.innerHTML=""; } else{ oUl.style.display="block" var result; var reg= new RegExp("^" +text.value, "i"); result=testdate.filter(function(item){ return item.match(reg); }); var litext=""; for(var i=0;i<result.length;i++){ litext+= "<li>"+result[i]+"</li>" oUl.innerHTML=litext; } } } </script> </html>