我需要从列表中选择列表项,然后执行添加事件处理程序等操作。我可以想到两种方法。
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>
使用ID -
for(i=0;i<3;i++)
{
document.getElementById("listItem-"+i).addEventListener("click",foo,false);
}
使用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命名方案。
问题:
答案 0 :(得分:3)
通过向包含元素(无序列表)添加单个事件处理程序并利用事件冒泡的概念,可以避免向每个列表项添加事件处理程序。在此单个事件处理程序中,您可以使用事件对象的属性来确定单击的内容。
您似乎想要将数组中的数据映射到列表项。从列表项ID中解析出数组索引可以工作,另一种方法是将列表项上的“键”值存储为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 :(得分:1)
如果您选择使用jQuery,它就像以下一样简单:
$('ul#list li').click(function () {
var i = this.id.split('-').pop();
alert( i );
});
答案 2 :(得分:1)
也许类似于:
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);
}
或者,从J cs回答和custom data attributes获得一些灵感:
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);
}
答案 3 :(得分:0)
如前所述,如果要检索li列表,则应在ul上使用getElementsByTagName,因为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);
})();
}
但您可以考虑为此目的进行事件委托。您只需将事件处理程序附加到父元素,并使用目标属性查找单击的元素。
document.getElementById("list").addEventListener("click", function(event)
{
var li = event.target;
if( li.nodeName.toLowerCase() == "li" )
{
...
}
}, false);