Recursão com vanilla JavaScript
doug-source
Posted on December 9, 2023
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>
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...
};
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++;
};
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;
};
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;
};
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);
};
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);
};
Fonte
Newsletter de Go Make Things
Posted on December 9, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
December 12, 2023