获取目标元素';s(数字)dom层次结构javascript

获取目标元素';s(数字)dom层次结构javascript,javascript,dom,Javascript,Dom,请不要使用库解决方案,不过如果您知道有这样的解决方案,我很乐意看看它们是如何做到这一点的。不太关心回退和跨浏览器支持 我有一个层次结构(将发生变化): 点击我! 我有一个事件监听器在点击我并获取一个事件对象。这很管用。是的 我想要event.targetdom层次结构数字索引。基本上,[0][1][2][0](虽然它可能会以数组的形式返回,[0,1,2,0],我没问题) 我知道这可以通过迭代父元素来实现。如果可能的话,我试图避免这种迭代 编辑 把我上次的编辑修改成白痴行为 我知道您希望避免迭

请不要使用库解决方案,不过如果您知道有这样的解决方案,我很乐意看看它们是如何做到这一点的。不太关心回退和跨浏览器支持

我有一个层次结构(将发生变化):


点击我!
我有一个事件监听器在
点击我
并获取一个事件对象。这很管用。是的

我想要
event.target
dom层次结构数字索引。基本上,
[0][1][2][0]
(虽然它可能会以数组的形式返回,
[0,1,2,0]
,我没问题)

我知道这可以通过迭代父元素来实现。如果可能的话,我试图避免这种迭代

编辑
把我上次的编辑修改成白痴行为

我知道您希望避免迭代,但这可能是最直接的策略:

$(document).on('click','a', function(e){
  var result=[];
  var count = function(e){
    if(e.parentNode != document.body ){
      result.push(e);
      count(e.parentNode);
   }else {
      return result;                                    
   }
 };
 count(e.target)
 console.log(result);
});
您试图避免迭代的原因是什么?dom是巨大的还是什么

您说“页面上的元素将非常快速地动态变化”,并且您正在“尝试用javascript创建一个数组,模拟元素在dom中的位置”。这意味着您不仅需要重新计算移动元素的索引路径,还需要重新计算未移动元素的索引路径


一句话:与其计算单个元素的路径,不如迭代整个层次结构,因为无论如何,您需要重新计算的不是一个,而是所有索引路径。

无需显式迭代即可获得索引的方法是使用数组indexOf方法

下面是它的样子,e是您的活动:

function getIndex(e){
  var t=e.target;
  return Array.prototype.indexOf.call(t.parentNode.childNodes,t);
}
这项技术有很多缺陷。首先,indexOf仅受最新浏览器的支持。其次,您需要调用技巧,因为节点列表不是数组。第三,childNodes可能返回比预期更多的节点,然后必须按节点类型进行筛选

要获得整个层次结构索引,只需在使用parentNode爬升DOM层次结构时单击并重复

作为记录,e.target也不是跨浏览器的,但我看到这是您已经在使用的

[更新]使用子节点而不是子节点的完整代码:

function getIndex(e) {
var index=[],
    t=e.target;

while (t!==document.body) {
    index.unshift(Array.prototype.indexOf.call(t.parentElement.children,t));
    t=t.parentElement;
}
return index;
}


如果不遍历父元素,那么如何计算元素的位置,包括父元素的位置?我不确定这是否可能。我也不确定,我希望有一些神奇的方法可以做到这一点。也许将DOM视为一个数组,并获取
事件的索引。target
?这些复杂之处超出了我对javascript=)的理解。也许可以用另一种方式来看待这个问题:元素是否以一种可以访问的方式知道它在dom中的深层位置?我想不出一种不进行迭代的方法来处理这个问题。在jQuery中,您可以使用
index()
方法来获取位置,但我确信它可能以某种智能的方式进行迭代。但我必须问:等级制度是由谁产生的?通过哪种方式?或者,换句话说,通过给元素提供类或其他属性,可以对元素进行多大程度的更改?也许正确的问题是:知道层次索引有什么意义,没有其他方法可以实现真正的目标吗?潜在的巨大dom,经常调用事件,在一个移动环境中><只是看看我疯狂想法的可行性。请使用迭代或递归,但不要混合它们。迭代(没有函数调用)会更快,但我们的最终条件是有缺陷的。可能有一些节点接收到单击事件,但在它们的节点中没有
document.body
。当我向dom添加新元素时,如果我知道索引路径,我可以将它们切分到一致数组中。@RandyHall我看到了。您并不真正关心索引路径,它只是一个中间计算步骤。附加问题:当从DOM中删除节点时,您计划如何继续?@cristop在从DOM中删除索引时拼接索引。我有可以处理dom添加/删除“侦听器”的自定义函数,因为旧的标准方法速度慢、不标准,现在已经不推荐了。@RandyHall我很想看看您是如何做到的!我从来没有得到过一个很好的答案,可以使用
t.parentElement.children
作为第一个参数,应该只返回元素,而不是节点。至少,这就是事件目标是如何在Chrome中排列的。“RANDYHALL,对了,这里你还必须考虑浏览器支持“孩子”。我得调查一下。我主要关注的是“现代”浏览器(主要是移动浏览器)。我用第二个更完整的片段更新了回复,其中使用了children。更新很好。我认为这是“最可行的”,尽管我希望有一些魔法属性,但似乎没有。
function getIndex(e) {
var index=[],
    t=e.target;

while (t!==document.body) {
    index.unshift(Array.prototype.indexOf.call(t.parentElement.children,t));
    t=t.parentElement;
}
return index;
}