我最近对 LanguageTool 和 Grammarly 等工具如何在屏幕上拼写错误的单词上显示红色下划线着迷。我想做一些类似的事情,但是在第一次在所说的词上显示下划线之后,在悬停一个词时显示带有同义词之类的丰富的弹出窗口。
这与浏览器扩展无关。请参阅我包含的指向 Grammarly 的 SDK 插件和 LanguageTool 的 API 示例的链接。
我知道 Grammarly 正在使用带槽的 Shadow DOM 来包装文本区域,但我仍然不知道他们如何能够(有效地)确定特定单词在文本区域中的位置。 LanguageTool 不使用 Shadow DOM。
当我检查它时,没有重复显示克隆的 HTML,我认为它们可能是为了将文本分解成标记,以便它们可以获得边界矩形——但事实并非如此。
<grammarly-editor-plugin><textarea></textarea></grammarly-editor-plugin>
我尝试使用 Canvas API 获取特定单词的尺寸,但这不足以确定其在文本区域中的位置,因为该单词可能位于比第一行更大的行上。
为了使这种方法起作用,他们必须获取 textarea 中的所有单词,计算它们的维度,并使用 textarea 的维度来确定目标单词在 textarea 中的哪一行;连同单词的尺寸,特别是宽度,它们将在文本区域内具有 x 和 y 位置。然而,这似乎太昂贵而且速度太慢,无法像他们的下划线显示的那样快。
我可以通过将每个单词包装在自己的范围内来使用 contenteditable,但这似乎不太理想。
有没有其他人知道他们还能如何确定文本区域中单词的 X 和 Y 位置。
你让我兴奋不已,但事实证明这并不是什么大挑战! :(
<!DOCTYPE html>
<head>
<style>
u{color:red;}
.con{width:500px; height:100px; border:1px solid black;}
</style>
</head>
<body>
<script>
const Correct=['Once','upon','a','time','there','were','three','little','pigs'];
function CheckSpelling(){
var S=Con.innerHTML.replace(/<u\>/g,'').replace(/<\/u\>/g,'');
var A=S.split(' ');
for(let i=0; i<A.length; i++){
if(Correct.includes(A[i])===false){A[i]='<u>'+A[i]+'</u>';}
} Con.innerHTML=A.join(' ');}
</script>
Change the words below and click spellcheck...<br><br>
<div id="Con" class="con" spellcheck="false" contenteditable="true">Once upon a time there were three little pigs</div>
<br>
<button onclick="CheckSpelling();">Check Spelling</button>
<br><br>
NB: Optionally you can automate the spellcheck by adding a oninput="CheckSpelling();" to the container.
</body>
</html>