如何以递归方式循环所有子项?

时间:2010-04-26 08:53:04

标签: javascript recursion loops for-loop children

我有以下内容:

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

10 个答案:

答案 0 :(得分:41)

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

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

答案 1 :(得分:28)

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

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

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

答案 2 :(得分:3)

不需要在所有子节点上调用'allDescendants'方法,因为方法本身已经这样做了。所以删除最后一个代码块,我认为这是一个合适的解决方案(á,notthé=])

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

答案 3 :(得分:1)

如果你有jquery并且你想获得所有后代元素,你可以使用:

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

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

答案 4 :(得分:1)

您可以使用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;
};

此函数返回元素的所有子元素。

答案 5 :(得分:1)

如果要在循环中创建项目,则应通过id =“”数据名称或其他方式留下索引。然后,您可以直接将它们编入索引,这对于大多数功能(如!!-F)而言将更快。对于1024位x 100个项目,效果很好,具体取决于您的工作。

SELECT
    r.r_id, r.r_name
FROM categories c
INNER JOIN category_recipe cr
    ON c.cat_id = cr.cat_id
INNER JOIN recipe r
    ON cr.r_id = r.r_id
WHERE
    c.cat_name = 'some category';

在大多数情况下,一旦加载项目,这将更快。仅在重新加载或安全域传输/登录/更正时擦洗页面,并且您将某件事重复两次。

答案 6 :(得分:0)

如果您使用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);
  }
}

答案 7 :(得分:0)

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

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

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

答案 8 :(得分:0)

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

答案 9 :(得分:-1)

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

    <ul class="listing-navigation__view">
        @if (Model.Pages != null && Model.Pages.Count > 0)
        {
            foreach (var p in Model.Pages)
            {
                if (p.Title == "Cancel View All" && Athena.Core.Tools.Misc.GetQueryStringAsInt("feature") == 1)
                {
                    continue;
                }
                if (p.Title == "Previous")
                {
                    rel = "rel=\"prev\"";
                }
                if (p.Title == "Next")
                {
                    rel = "rel=\"next\"";
                }
                <li class="page-@p.Title.ToLower().Replace(" ", "-") @(p.CurrentPage ? "current" : "")"><a href="@p.PageUrl" class="paging js-next-page" @Html.Raw(rel)>@p.Title</a></li>
            }
        }       
    </ul>