通过DIV模拟实现下拉选择框
Windows自带的下拉选择框的优先级别比大多数控件(media player也有类似的“毛病”)要高。因此,在具有绝对定位的层的网页里,一旦触发下拉框空间的onChange事件,将会引起整个页面的闪烁,这样将造成用户体验明显下降。于是,我参考了网上一篇未署名的帖子,模拟出了一个具有筛选功能的下拉选择控件。在我们Web Builder的控件库里,我们改进了该控件,使它具有了自学习的功能(能够将下拉选项中没有的,用户输入的值,自动学习并且存入到数据库)。
一下使我们改进后的下拉选择控件的代码:
1: 建立控件的内容由txt_SearchLimit、txt_SearchLimit_input、txt_SearchLimit_button、txt_SearchLimit_layer、txt_SearchLimit_table组成。
function BuildControl()
{
var tStrToolBar ="";//控件的内容
tStrToolBar += "<div id=\"txt_SearchLimit\" ctrlId=\"txt_SearchLimit\" selectedIndex=\"4\" value=\"0\" dspValue=\"选择时间范围\" style=\"\" class=\"\">";
tStrToolBar += " <span>";
tStrToolBar += "<input id=\"txt_SearchLimit_input\" value=\"\" type=\"text\" class=\"\" style=\"width:80px;border-right:none none none;\" onkeydown=\"displayLayer(this.parentElement.parentElement);\" onKeyup=\"lookUpInput(this.parentElement.parentElement);\" >";
tStrToolBar += "<input type=\"button\" id=\"txt_SearchLimit_button\" value=\" \" class=\"SelectButton\" style=\"width:18px;height:18px;\" onClick=\"showLayer(this.parentElement.parentElement)\"/>";
tStrToolBar += "</span>";
tStrToolBar += "<div id=\"txt_SearchLimit_layer\" bgcolor=\"#FFFFFF\" class=\"SelectTreeList\" style=\"width:80px;height:100px;\">";
tStrToolBar += " <table id=\"txt_SearchLimit_table\" width=\"80px\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" bgcolor=\"#FFFFFF\">";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">1</td>";
tStrToolBar += " <td >今天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">3</td>";
tStrToolBar += " <td >最近三天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">7</td>";
tStrToolBar += " <td >最近一星期</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">30</td>";
tStrToolBar += " <td >最近30天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">0</td>";
tStrToolBar += " <td >选择时间范围</td>";
tStrToolBar += " </tr></table>";
tStrToolBar += " </div>";
document.body.innerHTML = tStrToolBar;
}
{
var tStrToolBar ="";//控件的内容
tStrToolBar += "<div id=\"txt_SearchLimit\" ctrlId=\"txt_SearchLimit\" selectedIndex=\"4\" value=\"0\" dspValue=\"选择时间范围\" style=\"\" class=\"\">";
tStrToolBar += " <span>";
tStrToolBar += "<input id=\"txt_SearchLimit_input\" value=\"\" type=\"text\" class=\"\" style=\"width:80px;border-right:none none none;\" onkeydown=\"displayLayer(this.parentElement.parentElement);\" onKeyup=\"lookUpInput(this.parentElement.parentElement);\" >";
tStrToolBar += "<input type=\"button\" id=\"txt_SearchLimit_button\" value=\" \" class=\"SelectButton\" style=\"width:18px;height:18px;\" onClick=\"showLayer(this.parentElement.parentElement)\"/>";
tStrToolBar += "</span>";
tStrToolBar += "<div id=\"txt_SearchLimit_layer\" bgcolor=\"#FFFFFF\" class=\"SelectTreeList\" style=\"width:80px;height:100px;\">";
tStrToolBar += " <table id=\"txt_SearchLimit_table\" width=\"80px\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" bgcolor=\"#FFFFFF\">";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">1</td>";
tStrToolBar += " <td >今天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">3</td>";
tStrToolBar += " <td >最近三天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">7</td>";
tStrToolBar += " <td >最近一星期</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">30</td>";
tStrToolBar += " <td >最近30天</td>";
tStrToolBar += " </tr>";
tStrToolBar += " <tr onmouseover=\"moveWithOptions('highlight','white')\" onmouseout=\"moveWithOptions('','')\" onmouseup=\"selectedText(this.parentElement.parentElement.parentElement.parentElement)\">";
tStrToolBar += " <td style=\"display:none\">0</td>";
tStrToolBar += " <td >选择时间范围</td>";
tStrToolBar += " </tr></table>";
tStrToolBar += " </div>";
document.body.innerHTML = tStrToolBar;
}
2、加入控制控件的脚本
//用在自学习控件文本框的KeyPress事件中
function displayLayer(objAutoLearn)
{
if (event.keyCode == 9)
return;
var objLayer = objAutoLearn.lastChild;
if(objLayer !=null)
{
if(objLayer.style.display!="block")
{
objLayer.style.display ="block";
with(objLayer.style)
{
var objLearn = objAutoLearn.firstChild.firstChild;
var xy = getSelectPosition(objLearn);
posLeft = xy[0];
pixelTop = xy[1]+objLearn .offsetHeight;
}
if(objLayer.innerHTML == "")
{
//原本是通过Web Services从服务器端,获取数据的函数。这里用不上
//ShowAutoLearnData(objAutoLearn);
}
}
}
}
//用在自学习控件的按钮按下的的事件中
function showLayer(objAutoLearn)
{
var objLayer = objAutoLearn.lastChild;
if(objLayer !=null)
{
if(objLayer.style.display !="block")
{
objLayer.style.display ="block";
with(objLayer.style)
{
var objLearn = objAutoLearn.firstChild.firstChild;
var xy = getSelectPosition(objLearn);
posLeft = xy[0];
pixelTop = xy[1]+objLearn .offsetHeight;
}
if(objLayer.innerHTML == "")
{
ShowAutoLearnData(objAutoLearn);
}
}
else
{
objLayer.style.display ="none";
}
}
}
function displayLayer(objAutoLearn)
{
if (event.keyCode == 9)
return;
var objLayer = objAutoLearn.lastChild;
if(objLayer !=null)
{
if(objLayer.style.display!="block")
{
objLayer.style.display ="block";
with(objLayer.style)
{
var objLearn = objAutoLearn.firstChild.firstChild;
var xy = getSelectPosition(objLearn);
posLeft = xy[0];
pixelTop = xy[1]+objLearn .offsetHeight;
}
if(objLayer.innerHTML == "")
{
//原本是通过Web Services从服务器端,获取数据的函数。这里用不上
//ShowAutoLearnData(objAutoLearn);
}
}
}
}
//用在自学习控件的按钮按下的的事件中
function showLayer(objAutoLearn)
{
var objLayer = objAutoLearn.lastChild;
if(objLayer !=null)
{
if(objLayer.style.display !="block")
{
objLayer.style.display ="block";
with(objLayer.style)
{
var objLearn = objAutoLearn.firstChild.firstChild;
var xy = getSelectPosition(objLearn);
posLeft = xy[0];
pixelTop = xy[1]+objLearn .offsetHeight;
}
if(objLayer.innerHTML == "")
{
ShowAutoLearnData(objAutoLearn);
}
}
else
{
objLayer.style.display ="none";
}
}
}
3、获取下拉选项显示位置的函数
function getSelectPosition(elt)
{
var pos = new Object;
pos.x = 0;
pos.y = 0;
//一直找到body,如果相等就不加
while (elt&& elt.tagName.toUpperCase()!="BODY")
{
if (pos.y!=elt.offsetTop && elt.style.position !="absolute")
{
pos.x += elt.offsetLeft;
pos.y += elt.offsetTop;
if(elt.tagName.toUpperCase()!="HTML")
{
pos.x = pos.x -elt.scrollLeft;
pos.y = pos.y -elt.scrollTop;
}
}
elt = elt.offsetParent;
}
return ([pos.x,pos.y]);
}
{
var pos = new Object;
pos.x = 0;
pos.y = 0;
//一直找到body,如果相等就不加
while (elt&& elt.tagName.toUpperCase()!="BODY")
{
if (pos.y!=elt.offsetTop && elt.style.position !="absolute")
{
pos.x += elt.offsetLeft;
pos.y += elt.offsetTop;
if(elt.tagName.toUpperCase()!="HTML")
{
pos.x = pos.x -elt.scrollLeft;
pos.y = pos.y -elt.scrollTop;
}
}
elt = elt.offsetParent;
}
return ([pos.x,pos.y]);
}
4、查找用户输入项
function lookUpInput(objAutoLearn)
{
if(objAutoLearn.firstChild.firstChild.readOnly == true)
{
return;
}
var strInputValue = objAutoLearn.firstChild.firstChild.value;
var objTable = objAutoLearn.lastChild.firstChild;
if (objTable!= null && objTable.rows.length>0)
{
var rowCount = objTable.rows.length;
for(var i=0; i<rowCount;i++)
{
var objRow = objTable.rows[i];
var strValue = objRow.cells[0].innerText;
var strDspValue = objRow.cells[1].innerText;
if (strDspValue.indexOf(strInputValue)!=-1)
{
objRow.style.display ="block";
}
else
{
objRow.style.display ="none";
}
}
}
}
{
if(objAutoLearn.firstChild.firstChild.readOnly == true)
{
return;
}
var strInputValue = objAutoLearn.firstChild.firstChild.value;
var objTable = objAutoLearn.lastChild.firstChild;
if (objTable!= null && objTable.rows.length>0)
{
var rowCount = objTable.rows.length;
for(var i=0; i<rowCount;i++)
{
var objRow = objTable.rows[i];
var strValue = objRow.cells[0].innerText;
var strDspValue = objRow.cells[1].innerText;
if (strDspValue.indexOf(strInputValue)!=-1)
{
objRow.style.display ="block";
}
else
{
objRow.style.display ="none";
}
}
}
}
5、将选择的值放置到文本框并且给控件的value,Dspvalue属性赋值
function selectedText(objAutoLearn)
{
var objInput = objAutoLearn.firstChild.firstChild;
if (objInput !=null)
{
with(event.srcElement)
{
objInput.value= innerText;
objAutoLearn.setAttribute("value",previousSibling.innerText);
objAutoLearn.setAttribute("dspValue",innerText);
objAutoLearn.setAttribute("selectedIndex",parentElement.rowIndex);
}
objAutoLearn.lastChild.style.display ="none";
}
objInput.fireEvent("onChange");//引发控件的onChange事件
}
{
var objInput = objAutoLearn.firstChild.firstChild;
if (objInput !=null)
{
with(event.srcElement)
{
objInput.value= innerText;
objAutoLearn.setAttribute("value",previousSibling.innerText);
objAutoLearn.setAttribute("dspValue",innerText);
objAutoLearn.setAttribute("selectedIndex",parentElement.rowIndex);
}
objAutoLearn.lastChild.style.display ="none";
}
objInput.fireEvent("onChange");//引发控件的onChange事件
}