关于JS循环嵌套的DOM事件点击

大冒险 发布于 2014/03/04 09:08
阅读 2K+
收藏 0

     一共有四个框 ,每个框里有 几个列表项, 用循环嵌套 给 每个框里的列表项绑定点击事件后 ,随意点击列表项 都会 变成最后那 框里的列表被选中,而不是当前...  为什么? 难道是循环一下子 循环到最后了???   (贴代码 贴图)


var listSelect=(function(){
	   var itemBox=document.getElementById('itemCont');
	   var itemBoxList=getClass(itemBox,"item-cont-01");
	   var i,j;
	   var len=itemBoxList.length;
	   var l_now=0;
	   for(i=0;i<len;i++){   // 循环第一次  遍历 四个框
	   
		  var list=itemBoxList[i].getElementsByTagName('li');  
		  
		  for(j=0;j<list.length;j++){  // 循环第二次 遍历每个框中的列表 
		  
			 list[j].index=j;
			 
			 list[j].onclick=function(){   // 每个列表绑定点击事件
				 l_now=this.index;
				 list[l_now].className="item-curr";  
				 }	 
			  }   // end for j 
	    } //end for i
		})();



加载中
0
guoyao
guoyao

闭包的问题,var list=itemBoxList[i].getElementsByTagName('li') 这一句在循环结束后永远指向了itemBoxList[len].getElementsByTagName('li') 了,所以都会变成最后那 框里的列表被选中,要解决这个问题就要解决闭包带来的影响,代码如下:

var listSelect=(function(){
   var itemBox=document.getElementById('itemCont');
   var itemBoxList=getClass(itemBox,"item-cont-01");
   var i,j;
   var len=itemBoxList.length;
   var l_now=0;
   for(i=0;i<len;i++){   // 循环第一次  遍历 四个框
      var list=itemBoxList[i].getElementsByTagName('li'); 
      for(j=0;j<list.length;j++){  // 循环第二次 遍历每个框中的列表
         list[j].index=j;
         list[j].onclick=(function (listItems) {
            return function(){
              l_now=this.index;
              listItems[l_now].className="item-curr"; 
            }
         })(list);  
        }   // end for j
    } //end for i
})();


你的以上有太多可以优化的地方了:

var listSelect = (function(){
    var itemBox = document.getElementById('itemCont'),
        itemBoxList = getClass(itemBox,"item-cont-01"),
        i, j, list, length,
        len = itemBoxList.length;


   for(i = 0; i < len; i++){
      list = itemBoxList[i].getElementsByTagName('li'); 
      for(j = 0, length = list.length; j < length; j++){
         list[j].onclick = (function (listItems, index){
          return function(){
                listItems[index].className = "item-curr"; 
          }  
         })(list, j);
      }
    }
})();

以上代码还可以继续优化,你好好想想!
当然一楼的朋友说的很对,没必要给每个列表项都绑定事件,直接给父对象绑定事件

大冒险
大冒险
共用变量 除了用闭包 能不能 , 将变量作为 每个元素的 属性呢 比如 obj.now
0
ewangshi
ewangshi
没必要给每个列表项都绑定事件吧,直接给父对象绑定事件,  用this就能取到当前点击的对象
ewangshi
ewangshi
回复 @大冒险 : 绑定完事件之后list一直为最后一个框, this.className="item-curr"; 这样应该能实现你的功能
大冒险
大冒险
event.target? 好像我用 this.className 也可以 , 难道真是索引出了问题?
0
纠结名字

var l_now=0; 


把这个声明放到具体的click处理函数里就行了。

大冒险
大冒险
放在click 里??? l_now=this.index; 我已经将所以 this.index的索引 赋值了 , 还是不行呢? 但是不知道为什么 我是直接用 this.className 就可以 难道真是索引出了问题??
0
纠结名字

或者

list[l_now].className="item-curr"; 

改成

list[this.index].className="item-curr"; 

大冒险
大冒险
我这里已经将 l_now=this.index; 赋值了, 所以 一样的~~~
0
sxgkwei
sxgkwei
闭包了。。。
0
陈亦
陈亦
这个很显然是每个事件都共用了变量,解决方法是用闭包。
大冒险
大冒险
共用变量 除了用闭包 能不能 , 将变量作为 每个元素的 属性呢 比如 obj.now
0
mark35
mark35
这种情况最好是在父对象或者body上面绑定一个事件来处理,也方便调试
返回顶部
顶部