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

176
Visualizações
Trying to wrap each word a user enters into a contenteditable="true" element in a div

The behavior I'm looking to implement would wrap each word the user types in <div class="word"></div> as they type their message. The parent div they're typing into has contenteditable="true".

One complicating factor is that for this use case one "word" div may contain two words (imagine a name would be considered one "word" so e.g. <div class="word">Bob Smith</div> may occur). This means I can't just grab all of the textContent when the user presses space and split(" ") into an array to build the div.word DOM elements.

I'm thinking when the user presses space I can get all the child nodes of the contenteditable div and loop through them to check which is a textNode and which is not (i.e. a word already wrapped in div.word). Then for the text nodes only I can build a div.word DOM element and append all of these to the contenteditable div.

I hope that's clear. Here's sort of where I'm at:

<div id="editor" contenteditable></div>
#editor {
  border: 1px solid #333;
  padding: 10px;
}

#editor .word {
  background: yellow;
  display: inline-block;
}
const editorElement = document.getElementById('editor');


function handleSpacebarPress() {
  // Get all editor child nodes
  let editorChildNodes = [...editor.childNodes];
  
  // Clear editor of all child nodes
  editor.innerHTML = '';
  
  editorChildNodes.forEach(node => {
    // If node is a text node (not a div.word element)
    if (node.nodeType === 3) {
      // Create div.word
      let wordDiv = document.createElement('div');
      wordDiv.className = 'word';
      wordDiv.textContent = node.textContent;
      
      editor.appendChild(wordDiv);
    } 
    // Else node is already a div.word element
    else {
        editor.appendChild(node);
    }
  });
  
  // Return caret to end of editor
  const editorLength = editor.childNodes.length;
  const lastNode = editor.childNodes[editorLength - 1]; // Last editor node
  
  const range = document.createRange();
  const selection = window.getSelection();
  
  range.setStart(lastNode, 1);
  range.collapse(true);
  selection.removeAllRanges();
  selection.addRange(range);
}


editorElement.addEventListener('keydown', e => {
  if (e.code === 'Space') {
    handleSpacebarPress();
  }
});

You can view this on jsfiddle here.

Right now it seems to just place all words directly into the one div.word element and I can't seem to handle creating a new one for each word.

Any ideas?

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

0

I guess you want to achieve something like this: Highlighted Words Note how the spaces between the words are not highlighted and therefore have to be inside the main editor. You could fix this (as you pointed out in the comments) by adding spaces after each word in the editor and trim()-ming each word so that there are no spaces at the start or end of inner nodes.

You might to rethink your code, because it has some disadvantages.

  • Basically you are reimplementing what basic editors with custom syntax highlighting already do.
  • Manually setting the cursor position does not work, if you are editing in the middle of the editor.
  • Copy & pasting text wont trigger handleSpacebarPress

If you want to program the editor yourself, I suggest you use a function highlightWords that gets triggered after every change event (maybe with some artificial delay). In that function you can use a regular expression to find all the words according to your criteria and replace them with <span class=word>$1</span>.

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