功能实现:通过add()添加下拉列表框的值,通过crhtml()创建下拉列表框,此下拉列表框可以进行搜索列表框中的值,当选择某行时,把值传给指定文本框。
问题描述:当new一个对象时,一切操作正常。当new多个对象时,操作某个下拉列表框时,在页面显示方面操作的却是最后new的一个对象生成的下拉列表框,取值是当前操作下拉列表框的值(这是对的)。
我对JS对象才刚开始有所了解,希望高人帮忙指点下,先谢谢啦!// JavaScript Document
/* 查询人员对象 */
function FindStaffFramed(hidId,txtName){
this.length = 0; //保存数组长度
this.add = add; //添加对象 this.crhtml = newCreatHTML(this,hidId,txtName);
}/* 添加对象 */
function add(id,name){
this[this.length++] = new staffItem(id,name);
}/* 对象实体 */
function staffItem(id,name){
this.id = id;
this.name = name;
}/* newCreatHTML对象 */
function newCreatHTML(list,hidId,txtName){
 return function(){ 
this.crhtml = new CreatHTML(list,hidId,txtName);
this.crhtml.creat();
}
}/* 创建HTML对象 */
function CreatHTML(list,hidId,txtName){
this.hidId = hidId; //存储对象Id的对象Id
this.txtName = txtName; //存储对象Name的对象Id
this.creat = creat;
this.list = list;

this.selectIndex = -1; //当前选中的对象索引值,-1是未选中
this.findIndex = -1; //搜索项开始索引值
this.framed; //HTML总DIV对象
this.txtUserName; //HTML_输入UserName文本框对象
this.ulNames; //HTML_展示所有对象Name的UL对象 this.show = function(){ this.framed.style.display = "block"; }
}/* 创建HTML元素 */
function creat(){
var txtName = document.getElementById(this.txtName);
this.framed = document.createElement("div");
this.framed.style.left = getAbsoluteLeft(txtName) + 1;
this.framed.style.top = getAbsoluteTop(txtName) + txtName.offsetHeight;
this.framed.id = "framed";

var searchbar = document.createElement("div");

this.txtUserName = document.createElement("input");
this.txtUserName.id = "userName";
this.txtUserName.type = "text";
this.txtUserName.onchange = clearValue(this); this.txtUserName.style.width = txtName.offsetWidth - 30;
searchbar.appendChild(this.txtUserName);

var btnFind = document.createElement("input");
btnFind.id = "btnFind";
btnFind.type = "button";
btnFind.value = "Fi";
btnFind.onclick = toFindItem(this); searchbar.appendChild(btnFind);

this.framed.appendChild(searchbar);

this.ulNames = document.createElement("ul");
this.ulNames.id = "ulMain";
this.ulNames.style.width = txtName.offsetWidth - 2; for(var i = 0; i < this.list.length; i++){
this.creat[i] = document.createElement("li");
this.creat[i].id = "liUser" + i;
this.creat[i].onclick = clickItem(this,i); //单击选中对象,实现选中功能
this.creat[i].onmouseover = moveItem(this.creat[i]);
this.creat[i].onmouseout = moveItem(this.creat[i]);
this.creat[i].innerHTML = this.list[i].name;

this.ulNames.appendChild(this.creat[i]);
}
this.framed.appendChild(this.ulNames);
document.body.appendChild(this.framed);
}/* 单击选项时选择对象 */
function clickItem(obj,i){
return function(){
if(obj.selectIndex != -1){
obj.creat[obj.selectIndex].className = "";
obj.selectIndex = -1;
}
obj.selectIndex = i;
obj.creat[i].className = "selLi";

document.getElementById(obj.hidId).value = obj.list[obj.selectIndex].id;
document.getElementById(obj.txtName).value = obj.list[obj.selectIndex].name;
obj.framed.style.display = "none";
};
}/* 悬停在Li上时改变样式 */
function moveItem(objLi){
return function(){
if(objLi.className == "") objLi.className = "mouseLi"
else if(objLi.className == "mouseLi") objLi.className = "";
}
}/* 跳转到搜索方法 */
function toFindItem(obj){
return function(){ findItem(obj); }
}/* 处理搜索 */
function findItem(obj){
if(obj.txtUserName.value == "" || obj.txtUserName.value.length == 0) return;
if(obj.selectIndex != -1){
obj.creat[obj.selectIndex].className = "";
obj.selectIndex = -1;
}

for(var i = (obj.findIndex == -1 ? 0 : obj.findIndex + 1); i < obj.list.length; i++){
if(obj.list[i].name.substring(0,obj.txtUserName.value.length) == obj.txtUserName.value){
obj.creat[i].className = "selLi";
obj.selectIndex = i;
obj.findIndex = i;

var scroStart = parseInt(obj.ulNames.scrollTop); //滚动条最小开始位置
var scroStop = scroStart + parseInt(obj.ulNames.offsetHeight); //滚动条最大结束位置
var scroNow = (obj.selectIndex + 1) * parseInt(obj.creat[obj.selectIndex].offsetHeight); //滚动条当前位置
if(scroNow < scroStart)
obj.ulNames.scrollTop = obj.selectIndex *  parseInt(obj.creat[obj.selectIndex].offsetHeight);
else if(scroNow > scroStop){
obj.ulNames.scrollTop += scroNow - scroStop;
}
return;
}
}

if(obj.selectIndex == -1 && obj.findIndex != -1){
obj.findIndex = -1
findItem(obj);
} if(obj.selectIndex == -1 && obj.findIndex == -1){
alert("该用户名不存在!");
obj.txtUserName.select();
}
}/* 搜索框值改变时初始化搜索开始索引值 */
function clearValue(obj){
return function(){ obj.findIndex = -1; }
}/* 获取HTML对象left绝对值 */
function getAbsoluteLeft( ob ){
if(!ob){return null;}
var mendingOb = ob;
var mendingLeft = mendingOb .offsetLeft;
while( mendingOb != null && mendingOb .offsetParent != null && mendingOb .offsetParent.tagName != "BODY" ){
  mendingLeft += mendingOb .offsetParent.offsetLeft;
  mendingOb = mendingOb .offsetParent;
}
return mendingLeft ;
}/* 获取HTML对象top绝对值 */
function getAbsoluteTop( ob ){
if(!ob){return null;}
var mendingOb = ob;
var mendingTop = mendingOb .offsetTop;
while( mendingOb != null && mendingOb .offsetParent != null && mendingOb .offsetParent.tagName != "BODY" ){
mendingTop += mendingOb .offsetParent.offsetTop;
mendingOb = mendingOb .offsetParent;
}
return mendingTop ;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<script language="javascript" src="fsf_4.js"></script>
<style type="text/css">
#framed{
position:absolute; z-index:1; border:#3a8ed4 1px solid; background-color:#FFFFFF; font-size:12px;
}
#ulMain{
height:100px; overflow-x: hidden; overflow-y: auto; margin:0px; border-top:#3a8ed4 1px solid; text-indent:10px; list-style-type:none; cursor:hand;
}
#ulMain li{
text-decoration:none; height:20px; line-height:20px; display:block; width:100%; overflow:hidden;
}
.mouseLi{
text-decoration:none; background-color:#FFCB97; cursor:hand;
}
.selLi{
background-color:#003399; color:#FFFFFF;
}
#userName{
height:16px; width:170px;
}
#btnFind{
width:20px; height:20px; margin-left:2px; background:url(images/main_icon3.gif) no-repeat; border:0px #999999 solid; cursor:hand; border:#999999 1px solid;
}
</style>
</head><body style="margin:0px;">
<input id="user_id" type="hidden"  />
选择姓名1:<input id="user_name" type="text" readonly="true" onclick="showfsf()" style="cursor:hand;"  /><input id="user_id2" type="hidden"  />
选择姓名2:<input id="user_name2" type="text" readonly="true" onclick="showfsf2()" style="cursor:hand;"  /><input id="user_id3" type="hidden"  />
选择姓名3:<input id="user_name3" type="text" readonly="true" onclick="showfsf3()" style="cursor:hand;"  />
</body>
<script>
var fsf = null;
function showfsf(){
if(null == fsf){
fsf = new FindStaffFramed("user_id","user_name");
fsf.add("0","张三");
fsf.add("1","李四");
fsf.add("2","王五");
fsf.add("3","赵六");
fsf.add("4","陈七"); fsf.crhtml();
}else{
fsf.crhtml.show();
}
} var fsf2 = null;
function showfsf2(){
if(null == fsf2){
fsf2 = new FindStaffFramed("user_id2","user_name2");
fsf2.add("0","2张三2");
fsf2.add("1","2李四2");
fsf2.add("2","2王五2");
fsf2.add("3","2赵六2");
fsf2.add("4","2陈七2"); fsf2.crhtml();
}else{
fsf2.crhtml.show();
}
} var fsf3 = null;
function showfsf3(){
if(null == fsf3){
fsf3 = new FindStaffFramed("user_id3","user_name3");
fsf3.add("0","3张三3");
fsf3.add("1","3李四3");
fsf3.add("2","3王五3");
fsf3.add("3","3赵六3");
fsf3.add("4","3陈七3"); fsf3.crhtml();
}else{
fsf3.crhtml.show();
}
}
</script>
</html>

解决方案 »

  1.   

    问题应该出在this.add = add;试试:
    function FindStaffFramed(hidId,txtName){
        this.length = 0;                    //保存数组长度
        
         this.options = [];
        var me = this;
        this.add = function (id, name) { add.call(me.options, id, name); }    this.crhtml = newCreatHTML(this.options,hidId,txtName);
    }
      

  2.   

    我说下我的疑点:
    this.creat[i].onclick = clickItem(this,i);
    this.creat[i].onmouseover = moveItem(this.creat[i]);
    上述中直接传this过去操作显示会有影响,如果传this.creat[i]过去就不会有影响,这是为何呢?
      

  3.   

    JS并不是完全支持面向对象的,js的函数和object变量均是指针,只能通过自己实践,认清js的面向对象,本人也是菜鸟,LZ自己辛苦调试吧,代码太长,看着累
      

  4.   

    刚才运行一下你的代码,明白你的问题所在,将
    for(var i = 0; i < this.list.length; i++){
            this.creat[i] = document.createElement("li");    
            this.creat[i].id = "liUser" + i;
            this.creat[i].onclick = clickItem(this,i);        //单击选中对象,实现选中功能
            this.creat[i].onmouseover = moveItem(this.creat[i]);
            this.creat[i].onmouseout = moveItem(this.creat[i]);
            this.creat[i].innerHTML = this.list[i].name;
                
            this.ulNames.appendChild(this.creat[i]);
        }改为:
            this.creat = [];
            for (var i = 0; i < this.list.length; i++) {
                var li = document.createElement("li");
                li.id = "liUser" + i;
                li.onclick = clickItem(this, i);         //单击选中对象,实现选中功能
                  li.onmouseover = moveItem(li);
                li.onmouseout = moveItem(li);
                li.innerHTML = this.list[i].name;
                this.creat.push(li);
                
                this.ulNames.appendChild(this.creat[i]);
            }
    就可以了
      

  5.   

    实际上,你只是有一个很小的疏忽,就是没有在使用前定义this.creat为数组,这造成在调用checkItem的时候,obj.creat总是指向最后一个创建的。还有一种更简单的改法,就是将obj.creat[i].className = "selLi";改为:this.className = "selLi";