Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

83
Visualizações
Busque nodos DOM y devuelva el padre si algún descendiente contiene una coincidencia

Digamos que tengo lo siguiente:

 <div className="container"> <div id="one" class="item"> <div></div> <div></div> <div> <span>foo</span> </div> </div> <div id="two" class="item"> <div></div> <div></div> <div> <div>foo</div> </div> </div> <div id="three" class="item"> <span>foo</span> <div></div> <div> <span></span> </div> </div> <div id="four" class="item"> <span></span> <div></div> <div> <div> <span>foo</span> </div> </div> </div> </div>

Quiero devolver todos los elementos que contienen un lapso con contenido de texto "foo" en cualquier lugar dentro de ellos. En el ejemplo anterior, esperaría que se devolvieran 1, 2 y 4.

He escrito un método recursivo pero estoy tropezando en alguna parte, pienso en cómo estoy manejando el retorno. Esto actualmente devuelve todos los artículos.

 const hasFoo = (el) => { const isSpan = el.tagName?.toLowerCase() === "span"; const isMatch = el.innerText?.toLowerCase() === "foo"; if (isSpan && isMatch) { return true; } else if (el.children?.length) { const nodes = [...el.children]; return nodes.forEach(node => hasFoo(node)); } else { return false; } }; const container = document.getElementsByClassName("container")[0]; const nodes = [...container.children]; const filtered = nodes.filter(node => hasFoo(node));
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Un par de problemas.

className no es una alternativa válida para el atributo de clase. Por eso, document.getElementsByClassName("container") devuelve una matriz vacía.

return nodes.forEach(node => hasFoo(node)) SIEMPRE devolverá undefined . Según MDN ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach )

forEach() ejecuta la función callbackFn una vez para cada elemento de la matriz; a diferencia de map() o reduce(), siempre devuelve el valor indefinido y no se puede encadenar.

Use un bucle for en su lugar

 const hasFoo = (el) => { const isSpan = el.tagName?.toLowerCase() === "span"; const isMatch = el.innerText?.toLowerCase() === "foo"; if (isSpan && isMatch) { return true; } const nodes = [...el.children]; for (let i = 0; i < nodes.length; i++) { if (hasFoo(nodes[i])) return true; } return false; }
about 4 years ago · Juan Pablo Isaza Relatório

0

Otros han señalado los problemas con className y su forEach . Pero para una mejor experiencia que un bucle explícito, use Array.prototype.some , así:

 const hasFoo = (el) => (el .tagName ?.toLowerCase() === "span" && el .textContent ?.toLowerCase() === "foo") || [...el .children ?? []] .some (hasFoo) const foos = [... document .querySelectorAll (".container > *")] .filter (hasFoo) foos .forEach (div => div .classList .add ('hasFoo'))
 div {border: 1px solid #ccc; margin: .125em; padding: .125em;} span {border: 1px solid #000; padding: .125em;} div.hasFoo {background-color: yellow; border: 2px dotted #00f;}
 <div class="container"><div id="one" class="item"><div></div><div></div><div><span>foo</span></div></div><div id="two" class="item"><div></div><div></div><div><div>foo</div></div></div><div id="three" class="item"><span>foo</span><div></div><div><span></span></div></div><div id="four" class="item"><span></span><div></div><div><div><span>foo</span></div></div></div></div>

Aquí marcamos todos los <div> s con un borde claro, todos los <span> s con uno más oscuro y resaltamos todos los elementos secundarios de .container que tienen un foo -span con un fondo amarillo y un borde punteado.

about 4 years ago · Juan Pablo Isaza Relatório

0

No es recursivo, pero prefiero devolver una matriz filtrada de items según la condición/requisito.

 const items = Array.from(document.querySelectorAll('.item')); const itemsWithFooSpans = items.filter(item => { let hasFoo = false; const spans = item.querySelectorAll('span'); spans.forEach(span => { console.log('span: ', span); if (span && span.textContent && span.textContent === 'foo') { hasFoo = true; } }); return hasFoo; });
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda