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

273
Visualizações
RegEx/JS: Wrap innerHTML text elements in span including nested HTML elements

Given the innerHTML of an element, I'm trying to wrap each word in a span, and if the word is already wrapped, wrap the element.

e.g. Such that Here is a paragraph <span class="red">which</span> <div id="typed-effect">might</div> have nested elements

Becomes <span>Here</span> <span>is</span> <span>a</span> <span>paragraph</span> <span class="red">which</span> <span><div id="typed-effect">might</div></span> <span>have </span> <span>nested</span> <span>elements</span>

The components I have are:

  1. Extract the innerHTML and wrap in spans:
function wrapElementText(elementSelector) {
   const element = document.querySelector(elementSelector);
   const rawHTML = element.innerHTML;
   // Do magic to create list
   element.innerHTML = "";
   list.forEach((i, item) => {
     if (!item.contains(`<span`)) {
        element.innerHTML += `<span class="wrapped-text">${item}</span>`
      }
   }
};
  1. My best attempt is this ((\<.*?\>)|((\s?).*?(\s))) but it's returning e.g. <div id="typed-effect"> and might</div> as seperate groups when it should be one group <div id="typed-effect">might</div>.

Thanks so much in advance!

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Ok so i came up with these solutions:

  1. the regex approach(not recommended but what you asked for):
function wrapElementTextRegexp(elementSelector) {
    const element = document.querySelector(elementSelector);
    const chunks = element.innerHTML.match(/[a-zA-Z]+|(<[a-z][^>]+>.+<\/[^>]+>)/g);
    element.innerHTML = "";
    for(const chunk of chunks) {
        element.innerHTML += !chunk.startsWith('<span')
            ? `<span class="wrapped-text">${chunk}</span>`
            : chunk
    }
}

Here, the regexp is searching for a whole text or for a html tag pattern(simplified), in case it finds something that is not a span it wraps it in a span, otherwise it just return the original span

  1. the childNodes approach(imo better):
function wrapElementTextNodes(elementSelector) {
    const element = document.querySelector(elementSelector);
    const parsedInnerHTML = [...element.childNodes]
        .map(node => node instanceof HTMLElement
            ? node instanceof HTMLSpanElement
                ? node.outerHTML
                : `<span class="wrapped-text">${node.outerHTML}</span>`
            : node.textContent
                  .trim()
                  .split(/\s+/)
                  .map(word => `<span class="wrapped-text">${word}</span>`))
        .flat()
        .filter(chunk => !chunk.match(/><\//g))
        .join('')
  element.innerHTML = parsedInnerHTML;
}

Here we have access to the instances and we don't have to split the innerHTML since we're using childNodes, in the example i mapped the nodes by checking if the node was an actual HTMLElement and if yes if it was a HTMLSpanElement. After the first map i used a filter to remove from the array every empty node generated after the map(filtering out nodes like <span class="wrapped-text"></span>) and finally i join() the elements.

IMPORTANT NOTE wrapping a <div> element inside a <p> it's a bad practice, javascript won't recognize any childNode after the div(included) so for example if you have

<p>
    some
    <div>bad</div>
    example
</p>

the div and the node example will be omitted in element.innerHTML that, in this case, will return some. So make sure you correct your markup

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