【问题标题】:Finding DOM node index查找 DOM 节点索引
【发布时间】:2010-09-27 13:27:49
【问题描述】:

我想找到给定 DOM 节点的索引。这就像做的相反

document.getElementById('id_of_element').childNodes[K]

我想提取K 的值,因为我已经拥有对子节点和父节点的引用。我该怎么做呢?

【问题讨论】:

    标签: javascript dom


    【解决方案1】:

    现代原生方法可能包括Array.from(e.children).indexOf(theChild)

    不支持 IE,但 Edge 可以工作:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

    【讨论】:

      【解决方案2】:

      短一点,期望元素在elem中,返回k。

      for (var k=0,e=elem; e = e.previousSibling; ++k);
      

      Justin Dearing 发表评论后,我查看了我的答案并添加了以下内容:

      或者如果你更喜欢“while”:

      var k=0, e=elem;
      while (e = e.previousSibling) { ++k;}
      

      最初的问题是如何找到现有 DOM 元素的索引。我在这个答案中上面的两个示例都期望 elem 是一个 DOM 元素,并且该元素仍然存在于 DOM 中。如果您给它们一个空对象或没有 previousSibling 的对象,它们将失败。更简单的方法是这样的:

      var k=-1, e=elem;
      while (e) {
          if ( "previousSibling" in e ) {
              e = e.previousSibling;
              k = k + 1;
          } else {
              k= -1;
              break;
          }
      }   
      

      如果 enull 或如果其中一个对象中缺少 previousSibling,则 k 为 -1 .

      【讨论】:

      • @some,我不得不修改示例,看起来您必须将 e = e.previousSibling 移动到 for 循环的中间部分,并在 firefox 3.5 中进行空检查。
      • @Justin: "e=e.previousSibling" 在中间... for 循环声明 k=0 和 e=elem。然后它执行 e=e.previousSibling 直到 e===null。对于每个成功的循环,它都会将 k 加一。它适用于FF3.5.2。请解释您认为错误的地方。
      • @Justin:添加了更多示例。
      • 一些 - 如果我可以建议,如上/下是相对说明符,您可以考虑插入“以上两个示例 (1 & 2) 期望 elem" 代替您答案中的类似文本,因此,如果相关,有人知道您在说的是前两个示例(假设我是对的)。
      • @brunoais 在for 示例中,您使用previousElementSibling 并获得结果24,但在while 中您使用previousSibling,结果为49。我创建了一个新的testcase 他们都使用 previousElementSibling ,然后至少在我的有限测试中没有太大区别了。实际上,while 在 Win7 上的 FF20 中要快一些。
      【解决方案3】:

      在所有版本的 Safari、FireFox、Chrome 和 IE >= 9 中,无需任何框架的最短路径:

      var i = Array.prototype.indexOf.call(e.childNodes, someChildEl);

      【讨论】:

      • 注意:将e.childNodes 替换为e.children 以在其兄弟元素中查找元素的索引 - 而不是兄弟节点,其中包括文本和评论节点。
      • 为什么我们不能做类似e.parentNode.childNodes.indexOf(e) 的事情?编辑:我刚刚测试过。 NodeList 不是真正的Array,所以我们必须通过它的原型引入ArrayindexOf 的实现。令我惊讶的是,ArrayindexOfNodeLists 上起作用,无论这是有意还是巧合。
      • @StevenLu 您的第一个问题:NodeList 上的 indexOf 没有在 DOM 规范中定义,甚至在 DOM4 中也没有。你的最后一点:这是有意的。数组方法足够通用,几乎可以对任何具有长度属性的东西起作用。
      • @StevenLu 这是故意的。请参阅ECMA-262 Edition 5 第 244 页(pdf 中的 145),第 15.4.4.14 节的最后一个注释:“indexOf 函数是故意通用的;它不要求其 this 值是 Array 对象。因此它可以转移到其他类型的对象中用作方法。indexOf 函数能否成功应用于宿主对象取决于实现。"
      • 以数组分配为代价,它可以缩短为[].indexOf.call(children, el),除非这不符合浏览器兼容性声明(虽然我觉得这很令人惊讶)。
      【解决方案4】:

      与原始海报一样,我正在尝试

      查找给定 DOM 节点的索引

      但是我刚刚使用了一个点击处理程序,并且仅与它的兄弟姐妹有关。我最终无法让上述工作(因为毫无疑问,因为菜鸟,我尝试在 'this' 中替换 elem 但它没有工作)。

      我的解决方案是使用 jquery 并使用:

      var index = $(this).parent().children().index(this);
      

      它无需指定元素的类型即可工作,即:'h1' 或 id 等。

      【讨论】:

        【解决方案5】:

        使用原型之类的框架,您可以使用它:

        $(el).up().childElements().indexOf($(el))
        

        【讨论】:

          【解决方案6】:

          RoBorg 的回答有效...或者您可以尝试...

          var k = 0;
          while(elem.previousSibling){
              k++;
              elem = elem.previousSibling;
          }
          alert('I am at index: ' + k);
          

          【讨论】:

          • 你不能用while(elem=elem.previousSibling){k++;}替换while(elem.previousSibling){k++;elem = elem.previousSibling;}吗?
          【解决方案7】:

          我认为这样做的唯一方法是遍历父母的孩子,直到找到自己。

          var K = -1;
          for (var i = myNode.parent.childNodes.length; i >= 0; i--)
          {
              if (myNode.parent.childNodes[i] === myNode)
              {
                  K = i;
                  break;
              }
          }
          
          if (K == -1)
              alert('Not found?!');
          

          【讨论】:

            猜你喜欢
            • 2014-05-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-10
            • 1970-01-01
            • 2012-11-19
            • 2012-09-26
            • 1970-01-01
            相关资源
            最近更新 更多