硬编码的getElementsByClassName递归(element.className与element.classList.contains)

时间:2013-12-02 02:05:18

标签: javascript dom recursion getelementsbyclassname

经过几次硬编码递归getElementsByClassName方法的尝试后,我解决了以下问题:

var getElementsByClassName = function(className) {
  var result = [];

  function inspect(element) {
    var children = element.children;
    for(var i = 0; i < children.length; i++) {
      if(children[i].classList.contains(className)) {
        result.push(children[i]);
      }
      if(children[i].hasChildNodes) {
        inspect(children[i]);
      }
    }
  }

  inspect(document);
  return result;
};

但是,我无法理解为什么这个解决方案不起作用,考虑到className返回我们可以测试的值:

var getElementsByClassName = function(className) {
  var result = [];

  function inspect(element) {
    if (element.className === className) result.push(element);

    var children = element.children;
    for(var i = 0; i < children.length; i++) {
      inspect(children[i]);
    }
  }

  inspect(document);
  return result;
};

感谢您提前获得的帮助,如果您有任何其他改进我的代码的建议,请告知我们。

1 个答案:

答案 0 :(得分:1)

  1. 你的if语句需要更新,因为在某些情况下一个元素可以有多个类。目前您只是测试是否只有一个类。您可以使用contains方法使用indexOf检查它,如下所示,以查看所需的类名是否在列表中。
  2. 在调用您的递归调用时,您正在使用文档。我不太确定,但我相信你想要调用document.body ...这意味着你在第一次调用函数时尝试将var子项分配给document.children,但是你要调用 document.body.children 以及if语句 document.body.classname ...所以当调用递归调用时,它应该是 inspect(document.body)< /strong>。如果你想使用文档,那么你必须使用 document.childNodes ....但是最好使用document.body.children,因为document.childNodes在你的结果中添加空格每个元素之间。因此,如果有3个子节点,则document.body.children的长度为3,但document.childNodes的长度为5.您可以使用childnodes而不是childen执行相同的功能,但是if块中的contains方法在那种情况下使用会更好。
  3. 这是一种使用你的算法的解决方案,但是有更好的方法可以实现,你也可以在没有内部函数的情况下实现。

    Canvas