Como escrever um simples algoritmo de travessia de árvore de pré -encomenda no jQuery?
-
21-09-2019 - |
Pergunta
Eu gostaria de pegar o código encontrado aqui: http://www.jslab.dk/articles/non.recursive.preorder.traversal.part2
// HTML element
var root = document.documentElement;
recursivePreorder(root);
// Recusively find and handle all text nodes
function recursivePreorder(node) {
// If node is a text node
if (node.type == 3) {
// Do something with node
}
// else recurse for each child node
else {
for(var i=0; i<node.childNodes.length; i++)
recursivePreorder(node.childNodes[i]);
}
}
e converta -o em jQuery limpo.
Qualquer ideia? Eu sei que a recursão requer argumento.
Obrigado!
Solução
Como o Code Duck apontou, o jQuery atravessa nós em ordem de origem, profundidade-ou, como você chama, pré-encomenda. No entanto, contents
Só obtém nós de filhos imediatos, não descendentes. Experimente isso:
$(document).contents ().each (function processNodes ()
{
if (this.nodeType == 3)
doSomething (this); // do something with text node
else
$(this).contents ().each (processNodes);
});
Como um aparte, arguments.callee
está marcado para depreciação, daí a função nomeada (em oposição à anônima)
Outras dicas
A menos que essa seja uma tarefa de casa e você seja forçado a passar por toda a loucura loopy, certamente há uma maneira mais fácil com o jQuery para realizar o que você está tentando fazer ...
O JQuery possui um conjunto bastante robusto de seletores que permitirão apenas selecionar e retornar uma coleção de todo um tipo de elemento especificado em uma página ou elemento (por exemplo. Todas as tags de parágrafo em uma determinada tag Div). Eles serão devolvidos a você na ordem em que aparecerão no DOM (que é praticamente o que você recebe com o acima). Como alternativa, você pode usar um filtro como sugerido acima.
Se você precisar fazer isso em algum pedido específico, sugiro o uso de seletores ou filtros para pegar o elemento em que deseja começar e depois percorrer seus filhos recursivamente. JQuery tem uma função integrada para devolver os filhos de um determinado elemento.
Como um plugin jQuery: (também adiciona um recurso de interrupção (como jQuery.each
) e uma opção para pré ou pós-ordem; YMMV com pós-ordem)
$.fn.walk = function(visit, post_order) {
if(this.length === 0) { return; }
this.each(function(i) {
if (!post_order) {
if (visit.call(this, i, this) === false) { return false; }
}
$j(this).children().walk(visit, post_order);
if (post_order) { return visit.call(this, i, this); }
});
}
Eu acho que é tão simples quanto
var collection=$(document).contents().filter(function() { return this.nodeType == 3; });
Então, você pode executar seus comandos no collection
definir usando $.each
, ou se você deseja executar um método de jQuery no conjunto, não poderá atribuí -lo a uma variável e encadear o método para o final.