简体   繁体   English

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

[英]Get target element's (numeric) dom hierarchy javascript

No library solutions, please, though if you know of one that does this, I'm happy to take a look at how they do it. 请没有图书馆的解决方案,尽管如果您知道这样做的方法,我很乐于看一看他们是如何做到的。 Not terribly concerned with fall-backs and cross browser support. 不太担心后备和跨浏览器支持。

I have a hierarchy (that will change): 我有一个层次结构(将会改变):

<body>
    <div></div>
    <div>
        <div></div>
        <div></div>
        <div>
            <a>Click Me!</a>
        </div>
    </div>
</body>

I have an event listener on <a>Click Me!</a> and get an event object back. 我在<a>Click Me!</a>上有一个事件侦听器,并返回了一个事件对象。 That much works. 这么多的作品。 YEY! EY!

I want the event.target dom hierarchy numerical index. 我想要event.target dom层次结构数字索引。 basically, [0][1][2][0] (though it would probably return as an array, [0,1,2,0] , and that's okay with me). 基本上是[0][1][2][0] (尽管它很可能以数组[0,1,2,0] ,这对我来说还可以)。

I know this can be done with iterating through the parent elements. 我知道这可以通过遍历父元素来完成。 I'm trying to avoid that iteration , if possible. 如果可能的话我试图避免这种迭代

EDIT Redacting my last edit as an act of idiocy. 编辑将我的上次编辑编辑为愚蠢的行为。

A way to get an index without explicit iteration is to use the array indexOf method. 一种无需显式迭代即可获取索引的方法是使用数组indexOf方法。

Here is what it would look like, e being your event: 这是您的活动:

function getIndex(e){
  var t=e.target;
  return Array.prototype.indexOf.call(t.parentNode.childNodes,t);
}

There's a number of gotchas with this technique. 这种技术有很多陷阱。 First, indexOf is only supported by the most recent browsers. 首先,只有最新的浏览器才支持indexOf。 Second, you need the call trick because a NodeList is not an array. 其次,您需要调用技巧,因为NodeList不是数组。 Third, childNodes might return more nodes than expected and then you'll have to filter by node type. 第三,childNodes可能返回比预期更多的节点,然后您必须按节点类型进行过滤。

To get the whole hierarchy index, just rince and repeat as you climb up the DOM hierarchy with parentNode. 要获取整个层次结构索引,只需将其洗净并在使用parentNode爬上DOM层次结构时重复。

For the record, e.target is not cross-browser either, but I see this is what you're already using. 根据记录,e.target也不是跨浏览器,但是我看到这是您已经在使用的。

[Update] The full code, using children instead of childNodes: [更新]完整代码,使用子代而不是childNodes:

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

I know you want to avoid iteration, but it's probably the most straight forward strategy: 我知道您想避免迭代,但这可能是最直接的策略:

$(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);
});

For what reasons are you trying to avoid iteration? 您出于什么原因试图避免迭代? Is the dom huge or something? dom巨大还是什么?

You say that "The elements will dynamically change on the page quite rapidly" and that you are "attempting to create an array in javascript that mimics the position of elements in the dom". 您说“元素将在页面上快速动态变化”,并且您“正在尝试在javascript中创建一个模仿dom中元素位置的数组”。 It means that you'll need to recalculate not only the index path of the element(s) that moved, but also the index path of the ones that didn't move . 这意味着你将需要重新计算不仅是移动的元素(一个或多个)的索引路径, 而且没有动的那些的索引路径。

Bottom line: instead of calculating the path of an individual element, it makes sense to me to iterate through the whole hierarchy, as anyway you'll need to recalculate not one, but all index paths. 底线:遍历整个层次结构对我而言是有意义的,而不是计算单个元素的路径,因为无论如何,您都需要重新计算一个索引路径,而不是所有索引路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM