javascript - 如何测量 Google 文档中的单词/插入符位置?

标签 javascript google-docs html caret cursor-position

对于那些没有使用过 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/

相关文章:

javascript - 我无法使用页面底部的 Accordion 和 jquery 使空白消失

javascript - 解释 phi 系数函数如何在 Eloquent Javascript 中工作?

javascript - 当差异超过 100px 时,在浏览器上刷新页面并使用 JavaScript 调整大小

javascript - 向 Speech Synthesis API 添加暂停和播放功能

google-apps-script - Google Apps 脚本 UrlFetchApp 返回未经授权的错误 401

javascript - 在悬停时替换整个 div 并在悬停时切换回

javascript - 创建无缝嵌套滚动翻转

javascript - 选定的下拉列表重新加载页面并获取值

html - 获取 Google 文档 HTML 内容,然后使用 GmailApp 发送

php - 是否可以使用 Google Docs API 插入水平规则?