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

145
Visualizações
Why doesn't the custom caret get consistently positioned corectly in this case?

I am using the distance of the the span from the top to position the caret vertically, that works fine, and I am using the index of the string multiplied by the letter width to position the caret horizontally but that sometimes works, sometimes it doesn't.

Look for example at the second row, and click in the first "this", it doesn't work properly but if you click inside the last "this" the caret gets positioned correctly.

I can't figure out why, doesn't it mean that a mono-space font has the exact same with for each letter which I eyeballed here to be 10.1? Something doesn't work here and I can't figure out what. JsFiddle

let writeDiv = document.querySelector('#write');
let caret = document.querySelector('#caret')

writeDiv.addEventListener('click', (e) => {
    if(e.target.tagName == 'SPAN'){
        moveCaretOnClick(e)
    }

})

function moveCaretOnClick(e) {
    let y = window.getSelection().focusOffset * 10.1
    caret.style = `left: ${y}px; top: ${e.target.offsetTop + 3}px`; 
}
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap');
body, html{
    margin: 0;
  height: 100%;
  width: 100%;
}
#write {
  font-family: 'Roboto Mono';
    height: 100%;
    width: 100%;
    background: #1f2227;
    padding: 10px;
    color: white;
  box-sizing: border-box;
}
#caret{
    height: 15px;
    width: 3px;
    background: #80ff00;
    display: inline-block;
    position: absolute;
}



.RowSpan{
    width: 100%;
    display: inline-block;
    box-sizing: border-box;
    height: 20px;
}
<div id='write'>
    <span class='RowSpan'>This is some text</span>
    <span class='RowSpan'>this is some text this</span>
</div>
<div id='caret'></div>

Edit: My guess is that I need the exact dimension of the letters, otherwise, as you go further the line the distance increases more and more, because of multiplying for each letter. If you add more text the distance gets more and more further from the click.

So, somehow either get the exact dimension of the letters that's always consistent or find some other way.

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

0

A bit awkward but I fount the solution, it turns out I just had to add a 1 to the focusOffset before multiplying with each letter, otherwise it would basically skip a letter. I think because focusOffset starts with a 0

let writeDiv = document.querySelector('#write');
let caret = document.querySelector('#caret')



writeDiv.addEventListener('click', (e) => {
    if(e.target.tagName == 'SPAN'){
        moveCaretOnClick(e)
    }

})

function moveCaretOnClick(e) {
    let y = (window.getSelection().focusOffset + 1) * 9.6

    caret.style = `left: ${y}px; top: ${e.target.offsetTop + 3}px`; 
}
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap');
body{
    margin: 0;
}

#write {
  font-family: 'Roboto Mono';
    height: 300px;
    width: 1200px;
    background: #1f2227;
    padding: 10px;
    color: white;
}

#caret{
    height: 15px;
    width: 2px;
    background: #80ff00;
    display: inline-block;
    position: absolute;
}



.RowSpan{
    width: 100%;
    display: inline-block;
    box-sizing: border-box;
    height: 20px;
}
<div id='write'>
    <span class='RowSpan'>This is some text</span>
    <span class='RowSpan'>this is some text this more more text BIGGERT TEXT and some small text and some stuff -- __ !%^ () {} and some more text even </span>
</div>
<div id='caret'></div>

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