【问题标题】:How do I make this loop all children recursively?如何递归地使这个循环所有孩子?
【发布时间】:2011-02-12 07:38:21
【问题描述】:

我有以下几点:

for (var i = 0; i < children.length; i++){
   if(hasClass(children[i], "lbExclude")){
       children[i].parentNode.removeChild(children[i]);
   }
};

我希望它遍历所有孩子的孩子等(不仅仅是顶层)。我找到了这条线,这似乎是这样做的:

for(var m = n.firstChild; m != null; m = m.nextSibling) {

但我不清楚如果我做出这个转换,我会如何指代当前的孩子?我将不再让我澄清孩子的索引位置。有什么建议吗?

谢谢!

更新:

根据答案建议,我现在正在使用以下内容。这是正确/最有效的方法吗?

function removeTest(child) {
  if (hasClass(child, "lbExclude")) {
    child.parentNode.removeChild(child);
  }
}

function allDescendants(node) {
  for (var i = 0; i < node.childNodes.length; i++) {
    var child = node.childNodes[i];
    allDescendants(child);
    removeTest(child);
  }
}

var children = temp.childNodes;
for (var i = 0; i < children.length; i++) {
  allDescendants(children[i]);
};

【问题讨论】:

  • 你知道你在这里嵌套了多少个数组吗?
  • 简称m: m.parentNode.removeChild(m)。但是,可能会出现问题,因为删除节点然后获取其nextSibling(在for 子句中)将无法按预期工作。
  • @coshman,嵌套子节点的数量是可变的。
  • @dirk 我没想到。您有解决该问题的建议方法吗?

标签: javascript recursion loops for-loop children


【解决方案1】:
function allDescendants (node) {
    for (var i = 0; i < node.childNodes.length; i++) {
      var child = node.childNodes[i];
      allDescendants(child);
      doSomethingToNode(child);
    }
}

循环遍历所有子元素,对于每个元素,调用相同的函数并让它遍历该元素的子元素。

【讨论】:

  • 抱歉,您能否更明确地说明如何在我的案例中应用此功能?
  • 我认为更现代的版本是function allDescendants (node) { node.childNodes.forEach(child =&gt; { allDescendants(child); doSomethingToNode(child); }); }
【解决方案2】:

通常你会有一个可以在所有节点上递归调用的函数。这真的取决于你想对孩子们做什么。如果您只是想收集所有后代,那么element.getElementsByTagName 可能是更好的选择。

var all = node.getElementsByTagName('*');

for (var i = -1, l = all.length; ++i < l;) {
    removeTest(all[i]);
}

【讨论】:

  • 这只会获取元素,而不是所有节点。
  • 它们是通过 hasClass 方法测试的,所以我相信他们打算将它作为元素。
【解决方案3】:

没有必要对所有孩子调用“allDescendants”方法,因为该方法本身已经这样做了。所以删除最后一个代码块,我认为这是一个合适的解决方案(á,不是 thé =])

            function removeTest(child){     
                if(hasClass(child, "lbExclude")){
                    child.parentNode.removeChild(child);
                }
            }

            function allDescendants (node) {
                for (var i = 0; i < node.childNodes.length; i++) {
                  var child = node.childNodes[i];
                  allDescendants(child);
                  removeTest(child);
                }
            }           

            var children = allDescendants(temp);

【讨论】:

  • 对我来说缺少它的“childNodes”。非常感谢!
【解决方案4】:

如果你使用 js 库,就这么简单:

$('.lbExclude').remove();

否则如果你想获取一个节点下的所有元素,你可以原生收集它们:

var nodes = node.getElementsByTagName('*');
for (var i = 0; i < nodes.length; i++) {
  var n = nodes[i];
  if (hasClass(n, 'lbExclude')) {
    node.parentNode.removeChild(node);
  }
}

【讨论】:

  • 哎呀,没有看到@J-P 的答案。
【解决方案5】:

如果你有 jquery 并且想要获取所有可以使用的后代元素:

 var all_children= $(parent_element).find('*');

请注意,all_children 是一个 HTML 集合,而不是一个数组。当您只是循环时,它们的行为相似,但集合没有很多有用的Array.prototype 方法,您可能会喜欢。

【讨论】:

    【解决方案6】:

    您可以使用 BFS 查找所有元素。

    function(element) {
        // [].slice.call() - HTMLCollection to Array
        var children = [].slice.call(element.children), found = 0;
        while (children.length > found) {
            children = children.concat([].slice.call(children[found].children));
            found++;
        }
        return children;
    };
    

    这个函数返回元素的所有子元素。

    【讨论】:

      【解决方案7】:

      在现代浏览器或 babel 中最明确的方法是这样。假设您有一个 HTML 节点 $node 您想要递归其子节点。

      Array.prototype.forEach.call($node.querySelectorAll("*"), function(node) {
        doSomethingWith(node);
      });
      

      任何 DOM 节点上的 querySelectorAll('*') 都会为您提供 所有 NodeList 中元素的子节点。 NodeList 是一个类似数组的对象,因此您可以使用 Array.prototype.forEach.call 遍历此列表,在回调中逐个处理每个子对象。

      【讨论】:

      • 对不起我的无知!但是,'$node' 需要 JQuery 之类的东西吗?此解决方案对“香草”javascript 代码有效吗?
      • 不,$node 只是一个包含 HTMLNode 的变量名 - 不要被 $ 符号混淆 - 任何变量都可以包含 $。
      【解决方案8】:

      如果项目是在循环中创建的,您应该通过 id="" data-name 或其他方式留下索引。然后,您可以直接对它们进行索引,这对于大多数函数(例如 (!-F))会更快。对于 1024 位 x 100 个项目,效果非常好,具体取决于您的操作。

      if ( document.getElementById( cid ) ) {
       return;
      } else {
        what you actually want
      }
      

      一旦项目已经加载,这在大多数情况下会更快。仅在重新加载或安全域转移/登录/cors 时擦洗页面,并且您做某事两次。

      【讨论】:

        【解决方案9】:

        要将 所有 个后代作为数组获取,请使用以下命令:

        function getAllDescendants(node) {
            var all = [];
            getDescendants(node);
        
            function getDescendants(node) {
                for (var i = 0; i < node.childNodes.length; i++) {
                    var child = node.childNodes[i];
                    getDescendants(child);
                    all.push(child);
                }
            }
            return all;
        }
        

        【讨论】:

          【解决方案10】:
          TreeNode node = tv.SelectedNode;
          while (node.Parent != null)
          {
              node = node.Parent;
          }                    
          CallRecursive(node);
          
          
          private void CallRecursive(TreeNode treeNode)`
          {            
              foreach (TreeNode tn in treeNode.Nodes)
              {
                  //Write whatever code here this function recursively loops through all nodes                 
                  CallRecursive(tn);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-02
            • 1970-01-01
            • 2017-07-19
            • 2022-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-25
            相关资源
            最近更新 更多