Treewalker迭代

时间:2015-06-07 17:07:47

标签: javascript

是否可以跳过当前子树中的迭代并使用treewalker跳转到下一个节点? 示例

<nav>
    <p>paragraph</p>
    <ul>
        <li>one</li>
        <li>two</li>
    </ul>
    <p>paragraph</p>
</nav>

和js

var nav=document.getElementsByTagName("nav")[0];
    var tree=document.createTreeWalker(nav,NodeFilter.SHOW_ELEMENT,null,false);
    tree.firstChild(); // first paragraph
    tree.nextSibling(); // ul
    tree.firstChild(); // first li chid of ul
    tree.nextNode()||tree.nextSibling() // both return next li

在树木行者遇到第一个LI元素之后,有没有办法如何停止子树的迭代并直接跳到另一个段落?

2 个答案:

答案 0 :(得分:4)

您可以创建自定义filter

var filter = {
    acceptNode: function(n) {
        return n && n.parentNode && n.parentNode.tagName != "UL"
          ? NodeFilter.FILTER_ACCEPT
          : NodeFilter.FILTER_REJECT;
    }
};
var tree=document.createTreeWalker(nav, NodeFilter.SHOW_ELEMENT, filter, false);

答案 1 :(得分:2)

如果你在UL这样的节点上,并且想要跳过它的孩子,那么你想尝试进入下一个兄弟方向。但如果没有下一个兄弟,你需要上升到另一个级别再试一次。 (最终,您可能会到达walker的根,在这种情况下,您需要停止迭代并返回null。)

function nextNodeSkipChildren(tree) {
   var node;
   while (1) {
     if (node = tree.nextSibling()) return node; // return sibling if present
     if (!tree.parentNode()) return null;        // go up another level and repeat
   }
}

如果您已经在子节点(例如LI)并且想要跳过其余兄弟节点并继续使用“叔叔”或“大叔”,那么只需返回父节点即可在上述之前:

function nextNodeSkipRemainingSiblings(tree) {
  return tree.parentNode() && nextNodeSkipChildren(tree);
}