如何在单击时确定元素在一系列元素中的DOM位置

时间:2011-09-23 18:54:52

标签: javascript html5 javascript-events

在这种情况下,我有一系列列表项,每个列表项都有相应的内容区域。当单击列表项时,操纵相应的内容区域(即,如果单击第一个列表项,则将操纵第一个内容区)。

<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位置。

欢迎使用现代浏览器的解决方案。感谢。

4 个答案:

答案 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);