曾经遇到过一个需求的情况是这样的,我们提供给用户的输入框的可选择项只能满足用户的大部分情况的选择,但是有时候会遇到一些用户想要输入的数据是下拉项中所没有的,而用户不希望改变下拉项为输入框模式,需要说如果实在无法满足时,允许用户进行输入。由此产生了一个既可以实现下拉选择,又可以输入的下拉框功能。以下是我实现的代码:
/*------------------------------------------------------------------------------------------- 函数名称:jsLab_CreateSelectInput() 函数功能:创建支持下拉输入框对象 函数参数: selectId 下拉对象id inputTextName 输入框name属性 inputTextInitValue 输入框默认值 函数输出: 生成支持下拉的输入框,既可以输入又可以下拉选择 -------------------------------------------------------------------------------------------*/ function jsLab_CreateSelectInput(selectId, inputTextName, inputTextInitValue) { /*判断传入的下拉参数是下拉对象还是下拉框id*/ var selectDom = typeof(selectId) == "object" ? selectId : document.getElementById(selectId); /*若下拉框没有name属性则给下拉框创建name属性*/ if(!selectDom.name) { selectDom.name = selectDom.id; } if(typeof(inputTextName) == "undefined") { inputTextName = selectDom.name + "InputText"; } if(typeof(selectDom.parentNode) == "undefined") { return false; } /*下拉框所在的父节点以及父节点的定位位置*/ var selectParent = selectDom.parentNode; // store the raw position of selectDom's parent var selectParentRawWidth = selectParent.offsetWidth; var selectParentRawHeight = selectParent.offsetHeight; // clip the selectDom if(selectDom.style.position != "absolute") { //selectDom.style.position = "absolute"; } // store the raw position of selectDom var selectRawTop = selectDom.offsetTop; var selectRawLeft = selectDom.offsetLeft; var selectOffsetWidth = selectDom.offsetWidth; var selectOffsetHeight = selectDom.offsetHeight; /*设置下拉框可视部分*/ selectDom.style.clip = "rect(0px, "+ selectOffsetWidth +"px, "+ selectOffsetHeight +"px, "+(selectOffsetWidth - 4)+"px )"; /*判断下拉框是否存在inputText属性*/ if(typeof(selectDom.inputText) == "undefined") { var oInputText = document.createElement("input"); /*define the oInputText's style value for different browsers, 定义在不同浏览器下输入框的渲染样式*/ var inputTextHeight = selectOffsetHeight - 1; var inputTextBorderWidth = 2; var inputTextBorderStyle = "inset"; var inputTextBorderColor = "threedlightshadow"; var inputTextBorderBottomColor = inputTextBorderColor; var inputTextFontSize = selectOffsetHeight - 7; if(navigator && navigator.userAgent.toLowerCase()) { var navigatorInfo = navigator.userAgent.toLowerCase(); if(navigatorInfo.indexOf("opera") >= 0) { inputTextHeight += 1; inputTextBorderWidth = 1; inputTextBorderStyle = "ridge"; inputTextBorderColor = "threedlightshadow"; inputTextFontSize += 1; } else if(navigatorInfo.indexOf("firefox") >= 0) { inputTextHeight -= 2; inputTextBorderBottomColor = "threeddarkshadow"; } else if(navigatorInfo.indexOf("ie") >= 0) { inputTextHeight -= 2; inputTextBorderBottomColor = "threeddarkshadow"; } else { inputTextFontSize = inputTextFontSize - 1; } } // reset the position of select_parent //selectParent.style.width = (selectParentRawWidth - 4)+"px"; //selectParent.style.height = (selectParentRawHeight)+"px"; // define the clip input's style,定义输入框的可视样式 oInputText.style.display = "block"; oInputText.style.position = "absolute"; oInputText.style.width = (selectOffsetWidth - 20) + "px"; oInputText.style.height = inputTextHeight + "px"; //oInputText.style.top = selectRawTop + "px"; //oInputText.style.left = selectRawLeft + "px"; oInputText.style.fontSize = inputTextFontSize + "px"; oInputText.style.paddingLeft = "2px"; oInputText.style.borderWidth = inputTextBorderWidth + "px"; oInputText.style.borderStyle = inputTextBorderStyle; oInputText.style.borderColor = inputTextBorderColor; oInputText.style.borderBottomWidth = "1px"; oInputText.style.borderBottomColor = inputTextBorderBottomColor; oInputText.style.borderRightWidth = "0"; oInputText.name = inputTextName; oInputText.title = "支持手工输入方式,也可以下拉选择方式!"; selectDom.inputText = oInputText; } else { var oInputText = selectDom.inputText; } /*将输入框对象插入到下拉框前面*/ selectParent.insertBefore(oInputText,selectDom); /*将下拉框中选中的值初始化到输入框中*/ jsLab_SetSelectInputValue(selectDom, inputTextInitValue); /*给下拉绑定监听事件, 当下拉变化时,将下拉框的值初始化到输入框中*/ if(selectDom.attachEvent) { /*支持非火狐浏览器*/ selectDom.attachEvent("onchange",function(){ jsLab_BuildSelectInput(selectDom,selectOffsetWidth,selectOffsetHeight); }); } else { /*仅支持火狐浏览器*/ selectDom.addEventListener("change",function(){ jsLab_BuildSelectInput(selectDom,selectOffsetWidth,selectOffsetHeight); },false); } } /*------------------------------------------------------------------------------------------- 函数名称:jsLab_BuildSelectInput() 函数功能:根据下拉框的选择变化将下拉框的值赋到输入框中 函数参数: selectDom : 下拉对象id 函数输出: -------------------------------------------------------------------------------------------*/ function jsLab_BuildSelectInput(selectDom,selectOffsetWidth,selectOffsetHeight) { var selectedOption = selectDom.options[selectDom.selectedIndex]; var oInputText = selectDom.inputText; if(typeof(selectedOption.innerText) == "undefined") { oInputText.value = selectedOption.text; } else { oInputText.value = selectedOption.innerText; } oInputText.style.display = 'inline'; oInputText.style.color = "highlighttext"; oInputText.style.backgroundColor = "highlight"; selectDom.style.clip = "rect(0px, "+ selectOffsetWidth +"px, "+ selectOffsetHeight +"px, "+(selectOffsetWidth - 19)+"px )"; /*给输入框绑定click事件*/ oInputText.onclick = function() { oInputText.style.backgroundColor = ""; oInputText.style.color = ""; }; /*给下拉框绑定与输入相同事件*/ selectDom.onblur = oInputText.onclick; } /*------------------------------------------------------------------------------------------- 函数名称:jsLab_SetSelectInputValue() 函数功能:将下拉框中选中的值初始化到新创建的输入框中 函数参数: selectDom : 下拉对象id inputTextInitValue:输入框默认值 函数输出: -------------------------------------------------------------------------------------------*/ function jsLab_SetSelectInputValue(selectDom, inputTextInitValue) { var selectedOption = selectDom.options[selectDom.selectedIndex]; if(typeof(selectedOption.innerText) == "undefined") { selectDom.inputText.value = inputTextInitValue.length > 0 ? inputTextInitValue : selectedOption.text; } else { selectDom.inputText.value = inputTextInitValue.length > 0 ? inputTextInitValue : selectedOption.innerText; } }