JavaScript自定义Select组件:支持键盘导航与首字母筛选

作者:白露时间:2026-10-23 23:36:39浏览:103

本文介绍了一个基于JavaScript实现的自定义Select组件,支持通过键盘上下键选择选项、首字母快速筛选以及回车键确认取值。组件包含GetNewSelectStr和makeSelectBox两个核心函数,通过动态生成HTML表格结构模拟下拉列表,并结合事件监听实现交互逻辑,适用于需要增强原生Select体验的场景。

组件调用与参数说明

调用该组件时,可按照以下方式进行初始化:



1,tempStr=GetNewSelectStr(dataTable.value,"select"+rowIndex,true);


2,makeSelectBox("select"+rowIndex,tempStr,value,obj);



tempStr表示返回的下拉列表框体HTML字符串。


dataTable.value表示数据源,此处示例中为一张数据表。


"select"+rowIndex表示当前Select的ID号,由于页面可能存在多个Select,因此ID号是动态生成的。


true表示控制单击时是否出现下拉框体的标识。


value表示初始时显示在Select输入框中的值。


obj表示要显示Select的目标对象。



源代码如下:


核心功能实现代码

<script type="text/javascript">


var tempStr=GetNewSelectStr(dataTable.value,"select"+rowIndex,true);


makeSelectBox("select"+rowIndex,tempStr,value,obj);


var nowOpenedSelectBox = "";


var mousePosition = "";


var userList=null;


function selectThisValue(thisId,thisIndex,thisValue,thisString) {


var objId = thisId;


var nowIndex = thisIndex;


var valueString = thisString;


var sourceObj = $(objId);


var nowSelectedValue = document.getElementById(nowIndex+thisId).innerHTML;


hideOptionLayer(objId);


if (sourceObj) sourceObj.value = nowSelectedValue;


settingValue(objId,valueString);


selectBoxFocus(objId);


if (sourceObj.onchange) sourceObj.onchange();


}

function settingValue(thisId,thisString) {


var objId = thisId;


var valueString = thisString;


var selectedArea = document.getElementById(objId+"selectBoxSelectedValue");


if (selectedArea) {


if(navigator.appName.indexOf("Explorer") > -1){


selectedArea.innerText = valueString;


}

else{


selectedArea.textContent = valueString;


}
}
}

var l=0;


//显示下拉框中的值


function viewOptionLayer(thisId,Istask,flag) {


var objId = thisId;


var selectInfo="";


var optionHeight = 18; // 高


var optionMaxNum = 7; //


var optionInnerLayerHeight = "";


var selectBoxWidth =130;


var selectBoxHeight =17;


l=userList.Rows.length;


var optionLayer = document.getElementById(objId+"selectBoxs");


if(optionLayer.innerHTML=="")


{

if (l > optionMaxNum) optionInnerLayerHeight = "height:"+ (optionHeight * optionMaxNum) + "px";


selectInfo = "<table class='selectTable' id='" + objId + "selectBoxOptionLayer' cellpadding='0' cellspacing='0' border='0' style='position:absolute;z-index:100;'>";


if(Istask=="true")


{

selectInfo += " <tr>";


selectInfo += " <td height='" + selectBoxHeight + "' style='cursor:hand;' onClick=\"hideOptionLayer('"+ objId + "')\"></td>";


selectInfo += " </tr>";


selectInfo += " <tr>";


selectInfo += " <td style='height:2px;overflow:hidden;'></td>";


selectInfo += " </tr>";


}

else


{

selectInfo += " <tr style='height:24px;'>";


selectInfo += " <td height='" + selectBoxHeight + "' style='cursor:hand;' onClick=\"hideOptionLayer('"+ objId + "')\"></td>";


selectInfo += " </tr>";


}

selectInfo += " <tr style='height:17px;line-height:17px;border:none;'>";


selectInfo += " <td>";


selectInfo += " <div id='"+objId+"viewOptions' class='selectBoxOptionInnerLayer' style='width:" + selectBoxWidth + "px;" + optionInnerLayerHeight + "'>";


selectInfo += " <table class='selectTable' cellpadding='0' cellspacing='0' border='0' width='98%'>";


for (var i=0 ; i < l ; i++)


{

var nowValue = userList.Rows[i][userList.Columns[0].Name];


var nowText = userList.Rows[i][userList.Columns[0].Name];


if(Istask=="true")


{

selectInfo += " <tr>";


}

else


{

selectInfo += " <tr style='height:17px;line-height:17px; border:none;'>";


}

selectInfo += " <td id='"+i+objId+"' onMouseOver=\"resetStyle('"+objId+"');this.style.backgroundColor='#2c59aa';this.style.color='#ffffff';return true;\" onMouseOut=\"this.style.backgroundColor='#FFFFFF';this.style.color='#253449';return true;\" height='" + optionHeight + "' class='selectBoxOption' onMouseOver=\"this.className='selectBoxOptionOver'\" onMouseOut=\"this.className='selectBoxOption'\" onClick=\"selectThisValue('"+ objId + "'," + i + ",'" + nowValue + "','" + nowText + "')\" style='cursor:hand;'>" + nowText + "</td>";


// selectInfo += " <input type='hidden' id='"+ objId + "SelectBoxOptionValue" + i + "' value='" + nowValue + "'/>";


selectInfo += " </tr>";


}

selectInfo += " </table>";


selectInfo += " </div>";


selectInfo += " </td>";


selectInfo += " </tr>";


selectInfo += "</table>";


optionLayer.innerHTML=selectInfo;


}

if (flag && optionLayer.style.display=="none"){ optionLayer.style.display = "";optionLayer.focus();}


else


{

optionLayer.style.display = "none";


if(document.getElementById("level"))


{

document.getElementById("level").style.display="";


}

if(document.getElementById("priority"))


{

document.getElementById("priority").style.display="";


}
}

if(!flag){optionLayer.style.display = "";optionLayer.focus();}


for(var i=0;i<count;i++)


{

if(document.getElementById("select"+i+""+"viewOptions"))


{

document.getElementById("select"+i+""+"viewOptions").style.display="none";


}
}

document.getElementById(objId+"viewOptions").style.display="";


if(document.getElementById("level"))


{

document.getElementById("level").style.display="none";


}

if(document.getElementById("priority"))


{

document.getElementById("priority").style.display="none";


}

nowOpenedSelectBox = objId;


setMousePosition("inBox");


}

//支持首字母筛选、回车键取值、上下键选值功能


function firstLetter(thisId){


var count=0;


var selectedVal="";


if(document.getElementById(thisId+"viewOptions").style.display=="")


{

document.getElementById(thisId+"viewOptions").focus();


var asciiCode=String.fromCharCode(event.keyCode).toLowerCase();


var selectValue="";


if(event.keyCode==38)


{

for(var i=0;i<l;i++)


{

if(document.getElementById(i+thisId).className=="selectBoxOptionOver" && i>0)


{

document.getElementById(i+thisId).style.backgroundColor='#ffffff';


document.getElementById(i+thisId).style.color='#253449';


document.getElementById(i+thisId).className='selectBoxOption';


document.getElementById((i-1)+thisId).style.backgroundColor='#2c59aa';


document.getElementById((i-1)+thisId).style.color='#ffffff';


document.getElementById((i-1)+thisId).className='selectBoxOptionOver';


document.getElementById(thisId+"viewOptions").scrollTop= (i-1)*20;


count=1;


break;


}
}

if(count==0)


{

document.getElementById((l-1)+thisId).style.backgroundColor='#2c59aa';


document.getElementById((l-1)+thisId).style.color='#ffffff';


document.getElementById((l-1)+thisId).className='selectBoxOptionOver';


}
}

if(event.keyCode==40)


{

for(var i=0;i<l;i++)


{

if(document.getElementById(i+thisId).className=="selectBoxOptionOver" && i<l-1)


{

document.getElementById(i+thisId).style.backgroundColor='#ffffff';


document.getElementById(i+thisId).style.color='#253449';


document.getElementById(i+thisId).className='selectBoxOption';


document.getElementById((i+1)+thisId).style.backgroundColor='#2c59aa';


document.getElementById((i+1)+thisId).style.color='#ffffff';


document.getElementById((i+1)+thisId).className='selectBoxOptionOver';


if(i>10)


{

document.getElementById(thisId+"viewOptions").scrollTop= (i+1)*19;


}

else


{

document.getElementById(thisId+"viewOptions").scrollTop= (i+1)*10;


}

count=1;


break;


}
}

if(count==0)


{

document.getElementById(0+thisId).style.backgroundColor='#2c59aa';


document.getElementById(0+thisId).style.color='#ffffff';


document.getElementById(0+thisId).className='selectBoxOptionOver';


}
}

if(event.keyCode==13)


{

for(var i=0;i<l;i++)


{

if(document.getElementById(i+thisId).className=="selectBoxOptionOver")


{

selectedVal=document.getElementById(i+thisId).innerHTML;


var sourceObj = $(thisId);


hideOptionLayer(thisId);


if (sourceObj) sourceObj.value = selectedVal;


settingValue(thisId,selectedVal);


selectBoxFocus(thisId);


if (sourceObj.onchange) sourceObj.onchange();


document.getElementById(thisId+"viewOptions").style.display="none";


if(document.getElementById("level"))


{

document.getElementById("level").style.display="";


}

if(document.getElementById("priority"))


{

document.getElementById("priority").style.display="";


}

break;


}
}
}

for(var i=0 ; i < l ; i++)


{

selectValue=document.getElementById(i+thisId).innerHTML;


if(asciiCode==selectValue.substring(0,1))


{

resetStyle(thisId);


document.getElementById(i+thisId).style.backgroundColor='#2c59aa';


document.getElementById(i+thisId).style.color='#ffffff';


document.getElementById(i+thisId).className='selectBoxOptionOver';


document.getElementById(thisId+"viewOptions").scrollTop= i*19;


break;


}
}
}
}

//清除被选中的下拉列表值的样式


function resetStyle(thisId){


for(var i=0;i<l;i++)


{

document.getElementById(i+thisId).style.backgroundColor='#ffffff';


document.getElementById(i+thisId).style.color='#253449';


document.getElementById(i+thisId).className='selectBoxOption';


}
}

//隐藏下拉框


function hideOptionLayer(thisId) {


var objId = thisId;


var optionLayer = document.getElementById(objId+"selectBoxs");


if (optionLayer) optionLayer.style.display = "none";


if(document.getElementById("level"))


{

document.getElementById("level").style.display="";


}

if(document.getElementById("priority"))


{

document.getElementById("priority").style.display="";


}
}

function setMousePosition(thisValue) {


var positionValue = thisValue;


mousePosition = positionValue;


}

function clickMouse() {


if (mousePosition == "out") hideOptionLayer(nowOpenedSelectBox);


}

function selectBoxFocus(thisId) {


var objId = thisId;


var obj = document.getElementById(objId + "selectBoxSelectedValue");


obj.className = "selectBoxSelectedAreaFocus";


obj.focus();


}

function selectBoxBlur(thisId) {


var objId = thisId;


var obj = document.getElementById(objId + "selectBoxSelectedValue");


obj.className = "selectBoxSelectedArea";


}

function hiddenOptions(thisId){


document.getElementById(thisId+"viewOptions").style.display="none";


if(document.getElementById("level"))


{

document.getElementById("level").style.display="";


}

if(document.getElementById("priority"))


{

document.getElementById("priority").style.display="";


}
}

function makeSelectBox(index,newSelect,value,obj) {


newSelect=newSelect.replace(/(select0)/g,index);


$(obj).html(newSelect);


settingValue(index,value);


}

function GetNewSelectStr(table,index,IsTask){


userList=table;


var downArrowSrc = "../images/sanjiao.gif"; //三角


var downArrowSrcWidth = 16; //宽


var selectBoxWidth =130;


var selectBoxHeight =17;



newSelect="<div id='" + index + "selectBoxs' style='position:absolute;z-index:100;display:none;' onMouseOut=\"setMousePosition('out')\" onkeydown=\"firstLetter('"+ index + "')\"></div>"


newSelect += "<table class='selectTable' cellpadding='0' cellspacing='1' border='0' onClick=\"viewOptionLayer('"+ index + "','"+ IsTask + "',true)\" style='cursor:hand;height:18px;line-height:18px;' onkeydown=\"firstLetter('"+ index + "')\">";


newSelect += " <tr>";


newSelect += " <td>";


newSelect += " <table class='selectTable' cellpadding='0' cellspacing='0' border='0' style='height:18px;border:1px solid #9BB8C8;'>";


if(IsTask)


{

newSelect += " <tr>";


newSelect += " <td><div id='" + index + "selectBoxSelectedValue' name='selectBoxSelectedValue' class='selectBoxSelectedArea' style='width:" + (selectBoxWidth-downArrowSrcWidth-3)+ "px;height:" + selectBoxHeight + "px;overflow:hidden;' onBlur=\"selectBoxBlur('" + index + "');ValueEditd(this)\" onchange='ValueEditd(this)'></div></td>";


}

else


{

newSelect += " <tr style='height:18px;line-height:17px;'>";


newSelect += " <td><div id='" + index + "selectBoxSelectedValue' name='selectBoxSelectedValue' class='selectBoxSelectedArea' style='width:" + (selectBoxWidth-downArrowSrcWidth-4)+ "px;overflow:hidden;' onBlur=\"selectBoxBlur('" + index + "');\"></div></td>";


}

newSelect += " <td><img src='" + downArrowSrc + "' width='" + downArrowSrcWidth + "' border='0'></td>";


newSelect += " </tr>";


newSelect += " </table>";


newSelect += " </td>";


newSelect += " </tr>";


newSelect += "</table>";


return newSelect ;


}

</script>

作者最新文章