【问题标题】:How to determine DOM position of element in a series of elements when clicked单击时如何确定元素在一系列元素中的DOM位置
【发布时间】:2011-09-23 18:54:52
【问题描述】:

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

<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>

我的老派做法是给每个列表项和部分一个 id,例如“li1”、“li2”等以及“section1”、“section2”等。然后我会解析整数关闭被点击元素的 id 并操作相应的部分。

有没有办法在不需要额外的 id 属性的情况下确定这一点?例如,如果我单击第 3 个列表项并知道这是第 3 个,我可以使用 document.querySelector('div:nth-child(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 位置。

欢迎使用仅限浏览器的现代解决方案。

【问题讨论】:

    标签: javascript html dom-events


    【解决方案1】:

    所以我不知道你在这里做什么,但必须有一个更面向数据的方法。 就像 li 和 section 都指的是同一个 Product 或 Person 或其他东西,因此您可以通过该引用找到它。

    否则你可以使用 previousElementSibling 方法来计算你的位置

    var position = function(el) {
      var count = 1;
      for(var cur = el.previousElementSibling; 
              cur !== null; cur = cur.previousElementSibling) {
        count++;
      }
      return count;
    };
    

    gl

    【讨论】:

    • 在增加计数之前,您可能需要检查 nodeType 以避免 cmets 或 tagName 仅计算特定元素。
    【解决方案2】:

    我会使用类似的东西:

    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/

    【讨论】:

      【解决方案3】:

      如果可以使用 jQuery:$(elem).index()

      【讨论】:

      • 这很有趣...我将研究 API 以了解其工作原理。
      【解决方案4】:

      2016 年更新

      好吧,近 5 年后我又遇到了这个问题,只是这次我使用了一个更简单的解决方案,使用内置 Array 方法:

      var index = Array.prototype.indexOf.call(event.target.parent.children, event.target);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-30
        • 2021-05-01
        • 1970-01-01
        • 2020-04-07
        • 2017-03-25
        • 2020-03-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多