web-dev-qa-db-ja.com

選択したテキストの位置を取得する

現在、ブラウザで選択したテキストを取得しています。

window.getSelection();

次に、カスタムキーを押したときにそのテキストの上にツールチップを表示する必要があります(マウスをテキストの上に置くことができなくなったことに注意してください)。そのためには、選択したテキストの絶対位置が必要です。

それを行う方法はありますか、おそらくそのテキストをタグ内にラップしてからオフセットを取得しますか?すべてのブラウザではなく、Chromeで動作する必要があります。

38
Ecarrion

最も簡単な方法は、選択範囲の最初または最後に一時的なマーカー要素を挿入して、その位置を取得することです。私は以前にスタックオーバーフローでこれを行う方法を示しました: ユーザーテキスト選択の横に要素を配置するにはどうすればよいですか?

15
Tim Down
s = window.getSelection();

選択を返します。だから試して

s = window.getSelection();
oRange = s.getRangeAt(0); //get the text range
oRect = oRange.getBoundingClientRect();

oRectは、クライアント(固定)座標の外接する四角形になります。

57
Jerinaw

getBoundingClientRectを使用する前に、次のことを知っておく必要があります このメモ

CSSOMワーキングドラフトは、ボーダーボックスごとにClientRectを返すことを指定しています

そして、この「標準」によって:

インライン要素の場合、2つの定義は同じです。ただし、ブロック要素の場合、Mozillaは単一の長方形のみを返します。

したがって、この投稿を読んでいる人が、選択したテキストのより正確な位置とレイアウトの一般的な解決策を求めている場合は、次の方法をお勧めします。

オプション1:不可視要素の挿入 により、テキストの正確な開始点と終了点を検索します。次に、抽出された計算された線の高さとコンテナーの幅を使用して、選択された線の四角形を計算します。使用中のAPI: window.getComputedStyle

  • プロ:結果はテキストの各行で最も正確になります。
  • 欠点:1)選択が行の高さと幅の異なる複数のノードにまたがっている場合、アルゴリズムは複雑になります。 2)そして、単純な機能を実装する場合には時間がかかりすぎる計算アルゴリズムを実装する必要があります。

オプション2:各テキストを慎重にスタイル設定されたインライン要素でラップし、各ボックスのレイアウトを抽出して、結果を行にマージします。

  • プロ:すべての継続的な選択で機能します(つまり、現在の主流のブラウザー実装におけるすべてのケースを意味します)。テキストの各行に十分な精度。
  • 欠点:1) kerning のエラー幅が追加されるため、一部のケースでは結果が少し不正確になります。 2)非常に多くのテキストを選択すると遅い。

オプション2の場合、 rangeblock は、テキストの各行の絶対レイアウトを提供する簡単なAPIを備えた既存の実装です。

let block = rangeblock.extractSelectedBlock(window, document);
console.info("Text layout: " + JSON.stringify(block.dimensions));
// output: Text layout: {Left: 100, Top: 90, Width: 200, Height: 50}
0
lowatt