当用户单击某些文本时,我使用Window.getSelection获取用户单击位置的字符偏移量。当只有一个文本节点时,这非常有效,并且关于如何做到这一点有很多很好的答案。
但是,当我有两个或多个文本节点彼此相邻呈现时,我遇到了问题。这是一个复制问题的小提琴,但我将在这里介绍它:
用例:
我正在构建一个文本编辑器,并使用对用户按键做出反应的 Javascript 控制 DOM,而不是使用 contentEditable 容器。我想跟踪(并显示)用户的“光标”在文本中的位置(即,如果他们开始输入,将输入文本的位置),并让他们单击文本中的任意位置以手动设置光标到他们点击的地方。
HTML:
<p class="sentence">
<span class="word" index="0">There </span><span class="word" index="1">is </span><span class="word" index="2">a </span><span class="word" index="3">big, </span><span class="word" index="4">wonderful </span><span class="word" index="5">world.</span>
</p>
JavaScript:
$('.word').click(function() {
let word_index = $(this).attr('index');
let selection = window.getSelection();
let char_index = selection.focusOffset;
console.log('Clicked to set a new cursor @');
console.log('Word index = ' + word_index.toString() +
' / char index = ' + char_index.toString() );
});
简而言之,此代码打印 aword index和 acharacter index表示光标在文本中的位置,就好像它是可编辑输入一样。如果你点击“There”中“T”的左半部分,它会打印
Clicked to set a new cursor @
Word index = 0
/ char index = 0
单击“T”的右侧(这样光标将放置在其之后但“h”之前)将打印相同的单词索引,但字符索引为 1,因为光标现在放置在一个字符上,等等。
这也很有效......除了单击任何单词(第一个除外)的第一个字符的左半部分。单击“is”中“i”的左半部分(在单词索引 1、字符索引 0 处设置插入符号)会打印单词索引 1(正确)和字符索引 6(前一个单词的长度)。
当存在多个彼此相邻的文本节点时Window.getSelection
(或更具体地说, )不是计算这种字符偏移量的正确方法吗?selection.focusOffset
我需要使用其他库或方法吗?
解决该问题的一个“解决方案”是在每个单词周围应用边距,以在它们之间放置不可点击的间隙。在这种情况下,单击“i”的左半部分会给出正确的单词/字符索引(1,0 而不是 1,6),但会产生空格的副作用,如果用户不小心单击那里,则不会发生任何情况(此应用程序中存在严重的副作用,因此它并不是真正可行的“修复”)。看起来至少 3px 的边距总是返回正确的值,而 2px 或更小的边距总是返回错误的值。
我正在 Chrome 中进行测试,因为我最终将构建一个 Electron 应用程序,所以我想我只需要它在 Blink 中工作,但如果解决方案对于 Web 版本也与浏览器无关,那就太好了。
潇潇雨雨
子衿沉夜
相关分类