繁体   English   中英

如何测量谷歌文档中的单词/插入符号 position?

[英]How to measure word/caret position in Google Docs?

对于那些没有使用过 Google 文档编辑器的人,这里有一个关于它如何工作的简短说明:

  • Google 文档没有可见的可编辑文本区域或内容可编辑元素。
  • Google Docs 在单独的 iFrame 中侦听按键/按下/向上,他们将操作系统 cursor 放置在其中以进行事件侦听。
  • 当 iFrame 捕捉到事件时,Google 通过对可见文档执行等效操作来处理它。
  • Google Docs 中的“插入符号”是一个 DIV,其样式和脚本的外观和行为类似于操作系统 cursor。

顺便说一句,这是我的要求:

我正在开发一个与 Google 文档交互的插件,我需要能够做两件事:

  • 使用不透明的叠加 DIV 突出显示单词。
  • 判断一个词里面的cursor position。

关于如何处理这个问题,我已经用尽了很多想法,但到目前为止,我只设法为后一个问题找到了一个有缺陷的解决方案(我执行退格,确定文本更改的位置并撤消退格)。

我正在寻找您可以提出的所有最佳想法来解决这些问题。 它们不需要跨浏览器,但它们确实需要能够变成健壮的东西,也能处理诸如字体大小更改中线之类的事情。

一些额外的信息来解释 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>

经过更多的修改后,我得出的结论是,尝试以编程方式确定 cursor position 关于<span>内的字母是非常麻烦的 - 如果不是不可能的话,仅仅是因为<span>是可测量的最小元素(如果我错了,请纠正我)。

那么如何解决问题呢? 这是我最终做的:

  • 我创建了一个位于屏幕外的<div>
  • 我得到了当前段落的文本 ( <div class="kix-paragraphrenderer"> ) - 我可以得到整个文本,但想限制计算负载。
  • 我通过以下方式遍历其子项来提取段落的每个字符:
    • 循环段落的 linveviews ( <div class="kix-lineview"> )
    • 获取线景内容 ( <div class="kix-lineview-content"> )
    • 循环浏览 lineview 内容的文本块 ( <span class="kix-lineview-text-block"> )
    • 遍历文本块的<span>
    • 循环遍历<span>innerText
    • 我 append 我的屏幕外<div>中的每个字符都使用从当前<span>style.cssText中提取的当前应用样式
    • 对于附加的每个字符,我测量<div>的宽度并将其保存在一个数组中。 我现在每个字符都有一个 position。
  • 我测量了 cursor 的 position 相对于我的宽度,瞧——我知道 cursor 在文本中的位置。

这显然有点简化(我省略了有关不同元素的边距和填充的详细信息),但它涵盖了如何获得 cursor position 背后的想法。

它工作得很好,但是有很多陷阱并且需要进行大量测量。 最重要的是,如果您想将它用于任何事情,还需要对文本进行后解析,因为制表符、空格和换行符并不总是包含在innerText中(取决于它们在文本中的位置,谷歌可能会也可能不会通过定位新元素来制作它们)。

两年前我制作了类似 Kix 的 Google Docs。 对于任何 HTML 设计,是的,对于 IE6 也是如此:-) 如何? 我们只需要计算字母绝对值 position。怎么做? 用没有布局的内联元素替换 textNode,这很重要,然后使用 Element.getClientRects 我记得我还需要换行字母并通过快速可靠的 https 计算其position://developer.mozilla.org/en-US/docs/Web /API/Element.getBoundingClientRect

如何检测 home 和 end 键的行和换行的技巧是基于一些垂直启发式字母 position 的变化。 如果基线不同,则停止插入符号。 它非常快,带有任何标记且没有任何缓存。 圣杯:)

唯一无法解决的问题是对齐文本,因为字母是随机分布的,它们之间的空格是不可计算的。

那个项目现在已经死了http://webeena.com 糟糕的管理扼杀了它(我也差不多)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM