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

224
Visualizações
How can I get the position of the caret when it spans multiple rectangles?

I am making a WYSIWYG editor using contenteditable. Instead of using the caret that the browser displays, I need to draw my own simulated caret (to work around browser bugs). I need to get the exact position of the blinking caret, so I can draw my own caret at that position.

A call to document.getSelection().getRangeAt(0).getClientRects() almost works, but there's one edge case: when the caret is at the start or end of a line. See this demo:

const caretEl = document.getElementById('caret');

const updateFakeCaret = () => {
  const sel = document.getSelection();
  if (!sel) return undefined;
  if (sel.rangeCount !== 1) return undefined;
  const range = sel.getRangeAt(0);
  const clientRectList = range.getClientRects();
  const selectionRect = clientRectList.item(0);
  if (!selectionRect) return undefined;

  caretEl.style.top = selectionRect.top + window.scrollY + 'px';
  caretEl.style.left = selectionRect.left + window.scrollX + 'px';
  caretEl.style.width = selectionRect.width + 'px';
  caretEl.style.height = selectionRect.height + 'px';
};

document.addEventListener('selectionchange', updateFakeCaret);
window.addEventListener('resize', updateFakeCaret);
.editor {
  padding: 1em;
  white-space: pre-wrap;
  max-width: 20em;
  background-color: lightgrey;
}

#caret {
  position: absolute;
  z-index: 999;
  pointer-events: none;
  outline: 1px solid red;
}
<div class=editor contenteditable>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
<div id=caret></div>

When you click at the end of line 2, the cursor appears at the end of line 2. When you click at the start of a line 3, the cursor appears at the start of line 3. But those are the exact same location! Using the document.getSelection API, both positions appear identical, returning the same two client rectangles. But they're clearly not identical, because the browser (at least Chrome and Firefox) draws its own caret in different positions depending on the user interaction.

Is there a way to distinguish between "caret at end of line" and "caret at start of line"? Is there otherwise a reliable way to get the exact screen position of the caret?

about 4 years ago · Juan Pablo Isaza
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