[英]How to measure word/caret position in Google Docs?
For those who haven't worked with the Google Docs editor here's a short explanation of how it works:对于那些没有使用过 Google 文档编辑器的人,这里有一个关于它如何工作的简短说明:
With that out of the way, here's my request:顺便说一句,这是我的要求:
I'm working on a plugin that interacts with the Google Doc and I need to be able to do two things:我正在开发一个与 Google 文档交互的插件,我需要能够做两件事:
I've been exhausting a lot of ideas about just how to handle this, but so far I've only manage to get a buggy solution for the latter problem (I perform a backspace, determine where the text changed and undo the backspace).关于如何处理这个问题,我已经用尽了很多想法,但到目前为止,我只设法为后一个问题找到了一个有缺陷的解决方案(我执行退格,确定文本更改的位置并撤消退格)。
I'm looking for all the best ideas you can come up with to solve these problems.我正在寻找您可以提出的所有最佳想法来解决这些问题。 They don't need to be cross browser, but they do need to be able to be turned into something robust that will also handle things such as font size changed mid line.
它们不需要跨浏览器,但它们确实需要能够变成健壮的东西,也能处理诸如字体大小更改中线之类的事情。
A little bit of extra info explaining what a Google Doc looks like in HTML:一些额外的信息来解释 HTML 中的 Google 文档是什么样子的:
<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>
After more tinkering I came to the conclusion that it is extremely troublesome - if not impossible - to try and programmatically determine cursor position with regard to a letter inside a <span>
, simply because the <span>
is the smallest element that is measurable (correct me if I am wrong).经过更多的修改后,我得出的结论是,尝试以编程方式确定 cursor position 关于
<span>
内的字母是非常麻烦的 - 如果不是不可能的话,仅仅是因为<span>
是可测量的最小元素(如果我错了,请纠正我)。
So how to solve the problem?那么如何解决问题呢? Here's what I ended up doing:
这是我最终做的:
<div>
<div>
<div class="kix-paragraphrenderer">
) - I could get the entire text, but wanted to limit the computational load.<div class="kix-paragraphrenderer">
) - 我可以得到整个文本,但想限制计算负载。<div class="kix-lineview">
)<div class="kix-lineview">
)<div class="kix-lineview-content">
)<div class="kix-lineview-content">
)<span class="kix-lineview-text-block">
)<span class="kix-lineview-text-block">
)<span>
's of the text block<span>
innerText
of the <span>
<span>
的innerText
<div>
with the currently applied style extracted from style.cssText
of the current <span>
<div>
中的每个字符都使用从当前<span>
的style.cssText
中提取的当前应用样式<div>
and save this in an array.<div>
的宽度并将其保存在一个数组中。 I now have a position of each single character. This is obviously a bit simplied (I left out details about margins and paddings of the different elements), but it covers the idea behind how it's possible to get the cursor position.这显然有点简化(我省略了有关不同元素的边距和填充的详细信息),但它涵盖了如何获得 cursor position 背后的想法。
It works quite well, but there are many pitfalls and a lot of measuring required.它工作得很好,但是有很多陷阱并且需要进行大量测量。 On top of that it's also required to post-parse the text if you want to use it for anything, since tabs, spaces and linebreaks aren't always included in
innerText
(depending on where these are in the text, Google may or may not make them through positioning of new elements).最重要的是,如果您想将它用于任何事情,还需要对文本进行后解析,因为制表符、空格和换行符并不总是包含在
innerText
中(取决于它们在文本中的位置,谷歌可能会也可能不会通过定位新元素来制作它们)。
I made something like Kix two years ago Google Docs.两年前我制作了类似 Kix 的 Google Docs。 And for any HTML design and yes, for IE6 too:-) How?
对于任何 HTML 设计,是的,对于 IE6 也是如此:-) 如何? All we need is to compute letter absolute position. How?
我们只需要计算字母绝对值 position。怎么做? Replace textNode with inline element without layout, that's important, and then use Element.getClientRects I remember I also needed wrap just letter and compute its position via fast and reliable https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
用没有布局的内联元素替换 textNode,这很重要,然后使用 Element.getClientRects 我记得我还需要换行字母并通过快速可靠的 https 计算其position://developer.mozilla.org/en-US/docs/Web /API/Element.getBoundingClientRect
The trick how to detect lines and wraps for home and end keys was based on some vertical heuristic letter position change.如何检测 home 和 end 键的行和换行的技巧是基于一些垂直启发式字母 position 的变化。 Something like if base line is different, than stop caret walking.
如果基线不同,则停止插入符号。 It was pretty fast and with any markup and without any caching.
它非常快,带有任何标记且没有任何缓存。 Holy grail:)
圣杯:)
The only not resolvable problem was justified text, because letters were distributed randomly and spaces between them was not computable.唯一无法解决的问题是对齐文本,因为字母是随机分布的,它们之间的空格是不可计算的。
That project is dead http://webeena.com now.那个项目现在已经死了http://webeena.com 。 Bad management killed it (and me almost too).
糟糕的管理扼杀了它(我也差不多)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.