DEV Community

Cover image for Recursão com vanilla JavaScript
doug-source
doug-source

Posted on

Recursão com vanilla JavaScript

Nota: apenas traduzi o texto abaixo e postei aqui.

Em JavaScript, recursão ocorre quando você chama uma function de dentro dela até ou a menos que uma condição seja atendida. Hoje, vamos ver como funciona.

Um exemplo

Digamos que você tenha uma coleção de elementos aninhados, como este:

<div class="bg-1"> <div class="bg-2"> <div class="bg-3"> <div class="bg-4"> <div class="bg-5"> <div class="bg-6"> <div class="bg-7"> ... </div> </div> </div> </div> </div> </div> </div> 
Enter fullscreen mode Exit fullscreen mode

Você deseja escrever uma JavaScript function que permita obter a distância na DOM tree entre um element e seu parent. Por exemplo, .bg-5 está dois níveis acima de .bg-7.

Criando uma helper function

Primeiro, vamos criar uma levelsUp() helper function.

Passaremos um element e um selector como arguments. Também adicionaremos um terceiro argument que usaremos para rastrear a distância entre nosso element e um element com o selector.

var levelsUp = function (elem, selector, distance) { // Faça as coisas... }; 
Enter fullscreen mode Exit fullscreen mode

Não queremos que os usuários tenham que definir a distância como 0 toda vez que executarem a function.

Verificaremos se um valor para distance existe e, caso contrário, definiremos como 0. Em seguida, usaremos ++ para aumentar nosso valor de distance em 1.

var levelsUp = function (elem, selector, distance) { // Se distance não é definido ainda, configura ele para 0 if (!distance) { distance = 0; } // Aumenta a distance em 1 distance++; }; 
Enter fullscreen mode Exit fullscreen mode

A seguir, obteremos o parent do element atual com a propriedade elem.parentNode.

var levelsUp = function (elem, selector, distance) { // Se distance não é definido ainda, configura ele para 0 if (!distance) { distance = 0; } // Aumenta a distance em 1 distance++; // Obtêm o parent do element atual var parent = elem.parentNode; }; 
Enter fullscreen mode Exit fullscreen mode

Agora, podemos usar o método matches() para verificar se o parent corresponde ao selector.

Se o parent for compatível, podemos retornar nossa distance.

var levelsUp = function (elem, selector, distance) { // Se distance não é definido ainda, configura ele para 0 if (!distance) { distance = 0; } // Aumenta a distance em 1 distance++; // Obtêm o parent do element atual var parent = elem.parentNode; // Se alcançamos o parent, retorne a distance if (parent.matches(selector)) return distance; }; 
Enter fullscreen mode Exit fullscreen mode

Adicionando recursão

Agora, é aqui que entra a recursão.

Se o parent não corresponder, queremos executar levelUp() novamente, usando o parent como nosso element inicial. Também passaremos o selector e nossa distance atual.

E como a function precisa retornar um valor, retornaremos qualquer que seja o output de nossa function recursiva levelUp().

var levelsUp = function (elem, selector, distance) { // Se distance não é definido ainda, configura ele para 0 if (!distance) { distance = 0; } // Aumenta a distance em 1 distance++; // Obtêm o parent do element atual var parent = elem.parentNode; // Se alcançamos o parent, retorne a distance if (parent.matches(selector)) return distance; // Caso contrário, execute recursivamente levelUp() novamente return levelsUp(parent, selector, distance); }; 
Enter fullscreen mode Exit fullscreen mode

O método levelsUp() será executado várias vezes até encontrar uma correspondência ou atingir o window element e retornará qualquer que seja o valor final da distance (ou -1 se nenhuma correspondência for encontrada).

E com isso, agora temos uma function recursiva.

Um último detalhe

Se não houver nenhum selector correspondente, você pode acabar subindo o suficiente na DOM tree e atingir um element que não suporta o método matches() (como o window).

Antes de tentar usar matches(), vamos primeiro verificar se o parent suporta esse método. Caso contrário, retornaremos -1 e assumiremos que não há correspondência.

var levelsUp = function (elem, selector, distance) { // Se distance não é definido ainda, configura ele para 0 if (!distance) { distance = 0; } // Aumenta a distance em 1 distance++; // Obtêm o parent do element atual var parent = elem.parentNode; // Se você chegar a um elemento sem método matches(), desiste if (!parent.matches) return -1; // Se alcançamos o parent, retorne a distance if (parent.matches(selector)) return distance; // Caso contrário, execute recursivamente levelUp() novamente return levelsUp(parent, selector, distance); }; 
Enter fullscreen mode Exit fullscreen mode

Fonte

Newsletter de Go Make Things

Top comments (0)