2008-11-15 19 views
0

我需要从列表中选取列表项,然后执行像添加事件处理程序的操作。我可以想到两种做法。识别列表项索引 - 哪种方法更好?

HTML:

<ul id="list"> 
     <li id="listItem-0"> first item </li> 
     <li id="listItem-1"> second item </li> 
     <li id="listItem-2"> third item </li> 
    </ul> 
  1. 使用IDs-

    for(i=0;i<3;i++) 
    { 
        document.getElementById("listItem-"+i).addEventListener("click",foo,false); 
    } 
    
  2. 使用的childNodes属性 -

    for(i=0;i<3;i++) 
    { 
        document.getElementById("list").childNodes[i] 
        .addEventListener("click",foo,false); 
    } 
    

我使用的是第一种方法的原因是,在函数foo,如果我想在该项目位于列表中的索引,我可以通过拆分ID做到这一点 -

function foo() 
    { 
     tempArr = this.id.split('-');  
     index = tempArr[tempArr.length-1]; // the last element in the array 
    } 

我可以没有想到通过使用第二种方法做到这一点,也就是说,不使用id命名方案。

的问题:

  1. 我要如何使用第二种方法或任何更好的方法
  2. 是否有一些非常坏的影响后的第一个方法的指数?
+0

对于将空白视为文本节点的浏览器,第一种方法将失败。你并没有真正解释你为什么关心*索引*,所以我不打算推​​测是否有更好的解决方案。 – Shog9 2008-11-15 15:46:21

回答

3

通过向包含元素(无序列表)添加单个事件处理程序并利用事件冒泡的概念,可以避免向每个列表项添加事件处理程序。在这个单个事件处理程序中,您可以使用事件对象的属性来确定单击的内容。

看来你想要将数组映射到列表项。从列表项标识中解析出数组索引时会起作用,另一种方法是将“键”值作为expando存储在列表项上,并使用javascript对象属性来查找数据。

部分示例:

<li key="myKey"> 

//oData is a object (eg. var oData = {};) that has been populated with properties 
//whose value is the desired data (eg. oData["myKey"] = 123;) 

alert(oData[event.srcElement.key]); // alerts 123 

第一技术,你表现的就不好的影响,一个坏的影响在于,你最终许多列表项与许多事件处理程序被定义,这在某些时候会对性能有影响。

另请注意,您可能会无意中在您的循环中通过省略“i”的var关键字来创建全局变量。

1

如果您选择使用jQuery谈到那样简单:自J CS答案

var lis = document.getElementById("list").getElementsByTagName("li"); 

for (var i = 0, li; li = lis[i]; ++i) { 
    li.addEventListener("click", (function(pos) { 
    return function() { 
     alert(pos); 
    }; 
    })(i), false); 
} 

或者一些灵感和custom data attributes:类似

$('ul#list li').click(function() { 
    var i = this.id.split('-').pop(); 
    alert(i); 
}); 
1

或许真的到

var lis = document.getElementById("list").getElementsByTagName("li"); 

for (var i = 0, li; li = lis[i]; ++i) { 
    li.setAttribute("data-index", i); // Or whatever value you want... 
    li.addEventListener("click", function() { 
    alert(this.getAttribute("data-index")); 
}, false); 
} 
0

如前所述,如果你想检索li的列表,你应该使用getElementsByT agName,因为childNodes可能会检索一些文本节点以及li节点。

现在,如果您需要的是在事件处理程序中使用索引,则最好直接使用闭包以重新使用事件处理程序中的循环变量。

var lis = document.getElementById("list").getElementsByTagName("li"); 

for(var i = 0, l = lis.length; i < l; ++i) 
{ 
    (function(){ 

     // As a new variable will be created for each loop, 
     // you can use it in your event handler 
     var li = lis[i]; 

     li.addEventListener("click", function() 
     { 
      li.className = "clicked"; 

     }, false); 

    })(); 
} 

但是,您可能会考虑事件委派为此目的。您只需将一个事件处理程序附加到父元素,并使用target属性查找单击的元素。

document.getElementById("list").addEventListener("click", function(event) 
{ 
    var li = event.target; 
    if(li.nodeName.toLowerCase() == "li") 
    { 
     ... 
    } 
}, false);