对于那些没有使用过 Google 文档编辑器的人,这里有一个关于其工作原理的简短说明:
- Google 文档没有可见的可编辑文本区域或 contentEditable 元素。
- Google 文档在单独的 iFrame 中监听 keydown/press/up,并将操作系统光标放置在其中进行事件监听。
- 当 iFrame 捕获事件时,Google 会通过对可见文档执行等效操作来处理该事件。
- Google 文档中的“插入符号”是一个 DIV,其样式和脚本的外观和行为类似于操作系统光标。
既然如此,这是我的要求:
我正在开发一个与 Google 文档交互的插件,我需要能够做两件事:
- 使用不透明的叠加 DIV 突出显示单词。
- 确定光标在单词内的位置。
我已经用尽了很多关于如何处理这个问题的想法,但到目前为止,我只能设法为后一个问题找到一个有缺陷的解决方案(我执行退格键,确定文本更改的位置并撤消退格键)。
我正在寻找您能想到的所有最好的想法来解决这些问题。它们不需要跨浏览器,但它们确实需要能够变成健壮的东西,还可以处理诸如字体大小更改中线之类的事情。
一些额外信息解释了 Google 文档在 HTML 中的样子:
<wrapper> // Simplified wrapper containing margins, pagination and similar
<div class="kix-paragraphrenderer"> // single DIV per page wrapping all content
// Multiple paragraphs separated by linebreak created by Enter key:
<div class="kix-paragraphrendeder">...</div>
<div class="kix-paragraphrendeder">...</div>
<div class="kix-paragraphrendeder">
// Multiple wrapper divs created by Google's word wrapping:
<div class="kix-lineview">...</div>
<div class="kix-lineview">...</div>
<div class="kix-lineview">
// Single inner wrapper, still full width of first wrapper paragraph:
<div class="kix-lineview-content">
// Single wrapper SPAN containing full text of the line, but not display:block
<span class="kix-lineview-text-block">
// Multiple spans, one per new font change such as normal/bold text,
// change in font size, indentation and similar:
<span>This is normal text</span>
<span style="font-size:40px; padding-left:4px;">This larger text.</span>
<span style="font-weight:bold; padding-left:10px;">This is bold text</span>
<span style="padding-left:4px;">More normal text</span>
</span>
</div>
</div>
</div>
</div>
</wrapper>
最佳答案
经过更多的修改,我得出的结论是,尝试以编程方式确定 <span>
中的字母的光标位置,即使不是不可能,也是极其麻烦的。 ,仅仅因为<span>
是可测量的最小元素(如果我错了,请纠正我)。
那么如何解决这个问题呢?这就是我最终所做的:
- 我创建了一个位于屏幕外的
<div>
- 我获取当前段落的文本 (
<div class="kix-paragraphrenderer">
) - 我可以获得整个文本,但想要限制计算负载。 - 我通过按以下方式循环其子级来提取段落的每个单个字符:
- 循环浏览段落 (
<div class="kix-lineview">
) - 获取线 View 内容 (
<div class="kix-lineview-content">
) - 循环浏览线 View 内容的文本 block (
<span class="kix-lineview-text-block">
) - 循环
<span>
文本 block 的 - 循环
innerText
<span>
的 - 我将每个字符附加到屏幕外
<div>
使用从style.cssText
中提取的当前应用的样式当前<span>
- 对于附加的每个字符,我测量
<div>
的宽度并将其保存在数组中。我现在有了每个 Angular 色的位置。
- 循环浏览段落 (
- 我测量光标相对于宽度的位置,瞧 - 我知道光标在文本中的位置。
这显然有点简单(我省略了有关不同元素的边距和填充的详细信息),但它涵盖了如何获取光标位置背后的想法。
它工作得很好,但是有很多陷阱并且需要大量的测量。最重要的是,如果您想将文本用于任何用途,还需要对文本进行后解析,因为制表符、空格和换行符并不总是包含在 innerText
中。 (根据这些内容在文本中的位置,Google 可能会也可能不会通过新元素的定位来制作它们)。
关于javascript - 如何测量 Google 文档中的单词/插入符位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10091819/