
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:
<divclass="bg-1"><divclass="bg-2"><divclass="bg-3"><divclass="bg-4"><divclass="bg-5"><divclass="bg-6"><divclass="bg-7"> ...</div></div></div></div></div></div></div>
Você deseja escrever uma JavaScript function que permita obter a distância naDOM tree
entre umelement
e seuparent
. Por exemplo,.bg-5
está dois níveis acima de.bg-7
.
Criando uma helper function
Primeiro, vamos criar umalevelsUp() helper function
.
Passaremos umelement
e umselector
como arguments. Também adicionaremos um terceiro argument que usaremos para rastrear a distância entre nosso element e um element com o selector.
varlevelsUp=function(elem,selector,distance){// Faça as coisas...};
Não queremos que os usuários tenham que definir a distância como0
toda vez que executarem a function.
Verificaremos se um valor paradistance
existe e, caso contrário, definiremos como0
. Em seguida, usaremos++
para aumentar nosso valor dedistance
em1
.
varlevelsUp=function(elem,selector,distance){// Se distance não é definido ainda, configura ele para 0if(!distance){distance=0;}// Aumenta a distance em 1distance++;};
A seguir, obteremos o parent do element atual com a propriedadeelem.parentNode
.
varlevelsUp=function(elem,selector,distance){// Se distance não é definido ainda, configura ele para 0if(!distance){distance=0;}// Aumenta a distance em 1distance++;// Obtêm o parent do element atualvarparent=elem.parentNode;};
Agora, podemos usar o métodomatches()
para verificar se o parent corresponde ao selector.
Se o parent for compatível, podemos retornar nossadistance
.
varlevelsUp=function(elem,selector,distance){// Se distance não é definido ainda, configura ele para 0if(!distance){distance=0;}// Aumenta a distance em 1distance++;// Obtêm o parent do element atualvarparent=elem.parentNode;// Se alcançamos o parent, retorne a distanceif(parent.matches(selector))returndistance;};
Adicionando recursão
Agora, é aqui que entra a recursão.
Se o parent não corresponder, queremos executarlevelUp()
novamente, usando o parent como nosso element inicial. Também passaremos oselector
e nossadistance
atual.
E como a function precisa retornar um valor, retornaremos qualquer que seja o output de nossa function recursivalevelUp()
.
varlevelsUp=function(elem,selector,distance){// Se distance não é definido ainda, configura ele para 0if(!distance){distance=0;}// Aumenta a distance em 1distance++;// Obtêm o parent do element atualvarparent=elem.parentNode;// Se alcançamos o parent, retorne a distanceif(parent.matches(selector))returndistance;// Caso contrário, execute recursivamente levelUp() novamentereturnlevelsUp(parent,selector,distance);};
O métodolevelsUp()
será executado várias vezes até encontrar uma correspondência ou atingir o window element e retornará qualquer que seja o valor final dadistance
(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 naDOM tree
e atingir um element que não suporta o métodomatches()
(como owindow
).
Antes de tentar usarmatches()
, vamos primeiro verificar se o parent suporta esse método. Caso contrário, retornaremos-1
e assumiremos que não há correspondência.
varlevelsUp=function(elem,selector,distance){// Se distance não é definido ainda, configura ele para 0if(!distance){distance=0;}// Aumenta a distance em 1distance++;// Obtêm o parent do element atualvarparent=elem.parentNode;// Se você chegar a um elemento sem método matches(), desisteif(!parent.matches)return-1;// Se alcançamos o parent, retorne a distanceif(parent.matches(selector))returndistance;// Caso contrário, execute recursivamente levelUp() novamentereturnlevelsUp(parent,selector,distance);};
Fonte
Newsletter deGo Make Things
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse