2

Google ドキュメント エディタを使用したことがない人のために、その仕組みを簡単に説明します。

  • Google ドキュメントには、目に見える編集可能なテキストエリアや contentEditable 要素はありません。
  • Google ドキュメントは、イベントをリッスンするための OS カーソルを配置する別の iFrame でキーダウン/プレス/アップをリッスンします。
  • iFrame がイベントをキャッチすると、Google は表示されているドキュメントに対して同等の操作を実行してイベントを処理します。
  • Google ドキュメントの「キャレット」は、OS カーソルのように見えて動作するようにスタイルとスクリプトが作成された DIV です。

それが邪魔にならないように、ここに私の要求があります:

Google Doc とやり取りするプラグインに取り組んでおり、次の 2 つのことを実行できる必要があります。

  • 不透明なオーバーレイ 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>
4

2 に答える 2

4

<span>さらにいじくり回した後、 a は測定可能な最小の要素であるため、a 内の文字に関してカーソル位置をプログラムで決定しようとすることは、不可能ではないにしても、非常に面倒であるという結論に達しました<span>(間違っている場合は修正してください) )。

では、問題を解決するにはどうすればよいでしょうか。これが私がやったことです:

  • オフスクリーン ポジショニングを作成します<div>
  • 現在の段落のテキストを取得します ( <div class="kix-paragraphrenderer">) - テキスト全体を取得できましたが、計算負荷を制限したかったのです。
  • 次の方法で子をループすることにより、段落の各文字を抽出します。
    • 段落のリンビューをループします ( <div class="kix-lineview">)
    • ラインビュー コンテンツを取得する ( <div class="kix-lineview-content">)
    • ラインビュー コンテンツのテキスト ブロックをループします ( <span class="kix-lineview-text-block">)
    • <span>テキスト ブロックの をループします。
    • innerTextのループスルー <span>
    • オフスクリーンの各文字を、現在適用されている現在の<div> スタイルから抽出して追加しますstyle.cssText<span>
    • 追加された各文字の幅を測定し、<div>これを配列に保存します。私は今、各キャラクターの位置を持っています。
  • 幅と出来上がりに対するカーソルの位置を測定します-カーソルがテキスト内のどこに配置されているかを知っています。

これは明らかに少し単純化されています (さまざまな要素のマージンとパディングに関する詳細は省きました) が、カーソル位置を取得する方法の背後にある考え方をカバーしています。

これは非常にうまく機能しますが、多くの落とし穴があり、多くの測定が必要です。さらに、テキストを何かに使用する場合は、テキストを事後解析する必要があります。タブ、スペース、および改行が常に含まれているとは限らないためですinnerText(これらがテキスト内のどこにあるかによって、Google が作成する場合と作成しない場合があります)。それらは、新しい要素の配置によって異なります)。

于 2012-05-18T08:23:57.197 に答える
0

2 年前に Google Docs で Kix のようなものを作成しました。そして、どんな HTML デザインでも、はい、IE6 でも :-) どのように? 必要なのは、文字の絶対位置を計算することだけです。どのように?textNode をレイアウトなしのインライン要素に置き換えます。これは重要です。それから Element.getClientRects を使用してください/API/Element.getBoundingClientRect

ホームキーとエンドキーの行と折り返しを検出する方法は、垂直方向のヒューリスティックな文字位置の変更に基づいていました。キャレットの歩行を止めるよりも、ベースラインが異なる場合のようなもの。それは非常に高速で、マークアップがなく、キャッシュもありませんでした。聖杯:)

唯一解決できない問題は正当化されたテキストでした。これは、文字がランダムに配置され、文字間のスペースが計算できなかったためです。

そのプロジェクトは現在死んでいます http://webeena.com . 悪い管理はそれを殺しました(そして私もほとんどそうでした)。

于 2014-01-29T23:56:42.580 に答える