在这种情况下,为什么自定义插入符号不能始终如一地正确定位?

Why doesn't the custom caret get consistently positioned corectly in this case?

我使用 span 从顶部开始的距离来垂直定位插入符,效果很好,我使用字符串的索引乘以字母宽度来水平定位插入符,但有时会起作用, 有时不会。

例如,在第二行中单击第一个“this”,它不能正常工作,但如果您在最后一个“this”中单击,插入符号就会正确定位。

我不明白为什么,这是否意味着单色 space 字体与我在这里看到的每个字母都完全相同 10.1?有些东西在这里不起作用,我不知道是什么。 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>

编辑:我的猜测是我需要字母的确切尺寸,否则,随着线的进一步延伸,距离会越来越大,因为每个字母都会相乘。如果您添加更多文本,则点击距离会越来越远。

因此,要么以某种方式获得始终一致的字母的确切尺寸,要么找到其他方法。

有点尴尬,但我找到了解决方案,原来我只需要在与每个字母相乘之前在focusOffset中添加一个1,否则它基本上会跳过一个字母。我认为是因为 focusOffset0

开头

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>