選択範囲からプレーンテキストの URL を抽出する Chrome 拡張機能に取り組んでいますが、選択範囲は常に URL の一部になるため、左右にスキャンする必要があります。HTML要素を解析したくないし、textContentを再構築したくないので、基本的にinnerTextから選択範囲の周りに500文字を抽出する必要があります。
これは私がこれまでに持っているもので、非常にうまく機能していますが、ドキュメントオブジェクトを変更せずに元の状態に戻すより良い方法があると感じています...
// create a random 8 digit number - or bigger since we don't want duplicates
var randId = Math.floor(Math.random()*(90000000)+10000000);
var selection = document.getSelection();
var selectionRange = selection.getRangeAt(0);
// backup content, and then clone selection the user has made
var selectionContents = selectionRange.cloneContents();
var selectionContentsTxt = selectionContents.textContent;
// add random number to previous selection, this will expand selection
selectionContents.textContent = randId;
selectionRange.insertNode(selectionContents);
// find the random number in the document (in innerText in document.body)
var everything = document.body.innerText;
var offset = everything.indexOf(randId);
// restore backed up content to original state,- replace the selection
selectionContents = selectionRange.extractContents();
selectionContents.textContent = selectionContentsTxt;
selectionRange.insertNode(selectionContents);
// now we have the selection location offset in document.body.innerText
everything = document.body.innerText;
var extract = everything.substring(offset-250, offset+250);
extract は、ブラウザーによって評価された改行などを含む、抽出されたテキストを保持します。ちなみにこれはChromeのみなので、相互互換性はまったく必要ありません。これで、選択を解析できます-中央から端までURLを見つけるために、中央から解析を開始することが重要であるため、オフセットを知らずにgetSelection()のparentNodeからinnerTextを抽出しただけではないことに注意してください...
これを行うより良い方法はありますか?ドキュメント全体をDOMParserにコピーするかもしれませんが、元のドキュメントから getSelection を適用するにはどうすればよいですか?
- - - アップデート - - -
上記のコードを簡略化しました(マウスクリックで作業していることを忘れていたので、ダブルクリックしてテキストを選択した後、イベントクリックを検出しました)、今では document.body.innerText で caretOffset を見つけますが、それでも変更します文書化してから復元するので、これを行うためのより良い方法をまだ考えています。insertNode と deleteContents が何らかの形で悪いのでしょうか?
var randId = Math.floor(Math.random()*(90000000)+10000000);
var range = document.caretRangeFromPoint(event.clientX, event.clientY);
range.insertNode(document.createTextNode(randId));
var everything = document.body.innerText;
var offset = everything.indexOf(randId);
range.deleteContents();
var everything = document.body.innerText;
var extract = everything.substring(offset-250, offset+250);
document.getSelection().anchorNode.parentNode.normalize();
何かご意見は?