近来事多时少,所以博客更新的日期也比较滞后。其实大多时间,还是受感情牵制,于是便有了情绪的起伏不定,自然也没有做事的心思了。

关于文本框输入提示,网页上随处可见。比如新浪微博的登录,最常用的莫过于搜索输入了,比如百度搜索:

说说原理

它们都是根据用户在文本框输入的内容,然后再通过ajax请求服务器文件,读取到文件后再利用正则进行匹配,最后将符合要求的字符加入文本框下面的列表并显示,而且列表的数据是根据用户的输入来不断更新的。由于不懂服务器语言,这里请求的就拿一个固定js数组举例。

问题点

①. ajax无法解析返回的数组? 经研究,使用eval便可解析数组。

②. 无法通过用户输入的字符去动态更新可选列表? 经研究,能根据用户输入的字符长度(valLen),在利用substring(0,valLen)去匹配相关字符将其显示于列表。

③. ie6下使用键盘↓键选择可选列表后,回车无法隐藏可选列表? 经研究,可以用onkeyup代替onkeydown去操作可选列表。

实例效果和代码:

<style>
#ul{width:150px;border:1px solid #555;border-top:none;line-height:26px;display:none;}
#ul li{padding-left:10px;}
#ul .cur{background:#ccc;}
</style>

<input type="text" id="txt"/>
<ul id="ul">
</ul>

<script>
(function(){
//ajax四部曲
function ajax(url,fnSuccess,fnFail){
var oAjax=null;
if(window.XMLHttpRequest){
oAjax=new XMLHttpRequest();
}
else{
oAjax=new ActiveXObject("Microsoft.XMLHTTP");
}

oAjax.open("GET",url,true);

oAjax.send();

oAjax.onreadystatechange=function(){
if(oAjax.readyState==4 && oAjax.status==200){
fnSuccess(oAjax.responseText);
}
else{
if(fnFail){
fnFail();
}
}
}
}

var oTxt=document.getElementById("txt"),
oUl=document.getElementById("ul"),
c=-1,
oldVal=oTxt.value,
aLi=oUl.getElementsByTagName("li");;

oTxt.onkeyup=function(e){
var e=e||window.event;
eKey=e.keyCode;
ajax("sug.js",fnSuccess,fnFail);
}

function fnSuccess(str){
var e=e||window.event;
oUl.innerHTML="";
if(oTxt.value!=oldVal){
c=-1;
oldVal=oTxt.value;
}
if(oTxt.value){
var str=eval("("+str+")"), // 使用eval解析数组
val=oTxt.value.toLowerCase(),
valLen=oTxt.value.length;
for(var i=0;i<str.length;i++){
if(str[i].substring(0,valLen)==val){
var oLi=document.createElement("li");
oLi.innerHTML=str[i];
oUl.appendChild(oLi);
eleShow(oUl);
}
}

document.onclick=function(){
oUl.style.display="none";
}

if(oUl.style.display=="block"){
mouseLi();
keyLi();
}
}
}

function fnFail(){}

//键盘操作列表选择
function keyLi(){
switch(eKey){
// 40 下
// 38 上
// 13 enter
case 40:
c++;
listChange();
break;
case 38:
c--;
listChange();
break;
case 13:
eleHide(oUl);
oTxt.value=aLi.innerHTML;
break;
default:
break;
}
}

function listChange(){
if(c==aLi.length){
c=0;
}
for(var i=0;i<aLi.length;i++){
aLi[i].className="";
}
aLi.className="cur";
}

//鼠标操作列表选择
function mouseLi(){
for(var i=0;i<aLi.length;i++){
aLi[i].onclick=function(){
oTxt.value=this.innerHTML;
eleHide(oUl);
}
aLi[i].onmouseover=function(){
this.className="cur";
}
aLi[i].onmouseout=function(){
this.className="";
}
}
}

function eleShow(obj){
obj.style.display="block";
}

function eleHide(obj){
obj.style.display="none";
}
})()
</script>