在这种情况下,我有一系列列表项,每个列表项都有相应的内容区域。当单击列表项时,操纵相应的内容区域(即,如果单击第一个列表项,则将操纵第一个内容区)。
<ul>
<li>List item</li>
<li>List item</li>
<li>List item</li>
</ul>
<div>
<section>Content section</section>
<section>Content section</section>
<section>Content section</section>
</div>
我的oldschool这样做的方法是给每个列表项和部分一个id,例如“li1”,“li2”等,以及“section1”,“section2”等。然后,我将解析整数单击的元素的id并操作相应的部分。
有没有办法确定这个而不需要额外的id属性?例如,如果我点击第3个列表项并知道它是第3个,我可以使用document.querySelector('div:nth-child(3)')
来操纵第3个内容部分。我的问题是如何知道它是系列中第三个被点击开始的元素。
我的第一个想法的解决方案是这样的:
var target = e.target;
var parent = e.target.parentNode;
for (var i in parent.childNodes) {
if (parent.childNodes[i].nodeType == 1 && parent.childNodes[i] == target) {
// found it... i+1
}
}
与仅使用ID相比,这似乎是一项相当昂贵的操作,特别是如果有更多的列表项和内容部分。我希望有一些节点属性可以为我提供我尚未找到的正确DOM位置。
欢迎使用现代浏览器的解决方案。感谢。
答案 0 :(得分:1)
所以我不知道你在这里做了什么,但必须有一个更加面向数据的方法。 像li和section一样指的是同一个产品或Person或者其他东西,所以你可以通过引用找到它。
否则您可以使用previousElementSibling方法来计算您的位置
var position = function(el) {
var count = 1;
for(var cur = el.previousElementSibling;
cur !== null; cur = cur.previousElementSibling) {
count++;
}
return count;
};
gl
答案 1 :(得分:1)
我会使用类似的东西:
var target = e.target,
i = 0;
while(target = target.previousSibling) {
i += target.nodeType == 1;
}
alert('you clicked on '+i);
小提琴:http://jsfiddle.net/K5Qg9/1/
您还可以尝试使用数据库或将元素分配给元素expano onload:
var elems = document.getElementsByTagName('li'),
i=0;
for(; elems[i]; i++) {
elems[i].rel = i;
}
然后只需点击e.target.rel
onclick。小提琴:http://jsfiddle.net/UnrCt/
答案 2 :(得分:1)
如果你可以使用jQuery:$(elem).index()
答案 3 :(得分:0)
2016年更新
好吧,我差不多5年后又遇到了这个问题,这次我使用内置的Array方法使用了一个更简单的解决方案:
var index = Array.prototype.indexOf.call(event.target.parent.children, event.target);