2008-11-15 42 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);