簡體   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