14

テキストのブロック (多くの DOM ノードにまたがる可能性があります) を選択するとき、Javascript を使用して選択したテキストとノードを抽出することは可能ですか?

次の HTML コードを想像してください。

<h1>Hello World</h1><p>Hi <b>there!</b></p>

ユーザーが "World..." で始まる mouseDown イベントを開始し、"there!" の直後に mouseUp を開始した場合、次のように返されることを願っています。

Text : { selectedText: "WorldHi there!" },
Nodes: [ 
  { node: "h1", offset: 6, length: 5 }, 
  { node: "p", offset: 0, length: 16 }, 
  { node: "p > b", offset: 0, length: 6 } 
]

HTML をテキストエリアに入れようとしましたが、selectedText しか取得できません。私はその要素を試していません<canvas>が、それは別のオプションかもしれません。

JavaScript でない場合、Firefox 拡張機能を使用してこれを可能にする方法はありますか?

4

6 に答える 6

15

あなたはでこぼこの乗り物に乗っていますが、これはかなり可能です。主な問題は、IEとW3Cが選択に対して完全に異なるインターフェースを公開することです。したがって、クロスブラウザー機能が必要な場合は、基本的にすべてを2回記述する必要があります。また、いくつかの基本的な機能が両方のインターフェイスにありません。

Mozilla開発者接続には、W3Cの選択に関する話があります。MicrosoftのシステムはMSDNに文書化されています。PPKの範囲の紹介から始めることをお勧めします。

これが私が機能すると信じているいくつかの基本的な機能です:

// selection objects will differ between browsers
function getSelection () {
  return ( msie ) 
    ? document.selection
    : ( window.getSelection || document.getSelection )();
}

// range objects will differ between browsers
function getRange () {
  return ( msie ) 
      ? getSelection().createRange()
      : getSelection().getRangeAt( 0 )
}

// abstract getting a parent container from a range
function parentContainer ( range ) {
  return ( msie )
      ? range.parentElement()
      : range.commonAncestorContainer;
}
于 2008-12-12T23:19:35.623 に答える
8

私のRangyライブラリは、IE < 9 および他のすべての主要なブラウザーでさまざまな API を統合し、getNodes()その Range オブジェクトに関数を提供することで、あなたの役割を果たします。

function getSelectedNodes() {
    var selectedNodes = [];
    var sel = rangy.getSelection();
    for (var i = 0; i < sel.rangeCount; ++i) {
        selectedNodes = selectedNodes.concat( sel.getRangeAt(i).getNodes() );
    }
    return selectedNodes;
}

選択したテキストを取得するのは、すべてのブラウザーで非常に簡単です。ランジーではただ

var selectedText = rangy.getSelection().toString();

ランジーなし:

function getSelectedText() {
    var sel, text = "";
    if (window.getSelection) {
        text = "" + window.getSelection();
    } else if ( (sel = document.selection) && sel.type == "Text") {
        text = sel.createRange().text;
    }
    return text;
}

node文字オフセットに関しては、選択範囲内の任意のノードに対してこのようなことを行うことができます。折りたたまれたスペース、CSS によって非表示にされたテキスト、CSS によって通常のドキュメント フローの外に配置されたテキスト、およびブロック要素によって暗示された改行<br>、およびその他の微妙な点は考慮されていないため、これは必ずしもドキュメント内の表示可能なテキストを表しているとは限りません。

var sel = rangy.getSelection();
var selRange = sel.getRangeAt(0);
var rangePrecedingNode = rangy.createRange();
rangePrecedingNode.setStart(selRange.startContainer, selRange.startOffset);
rangePrecedingNode.setEndBefore(node);
var startIndex = rangePrecedingNode.toString().length;
rangePrecedingNode.setEndAfter(node);
var endIndex = rangePrecedingNode.toString().length;
alert(startIndex + ", " + endIndex);
于 2012-04-09T15:55:32.987 に答える
0

範囲だけが必要な場合は、はるかに短い方法があります。

function getRange(){
    return (navigator.appName=="Microsoft Internet Explorer")
        ? document.selection.createRange().parentElement()
        : (getSelection||document.getSelection)().getRangeAt(0).commonAncestorContainer
}
于 2012-01-25T15:09:30.240 に答える
-1

http://javascript.internet.com/page-details/copy-selected-text.htmlから開始することをお勧めします

于 2008-12-11T22:26:08.737 に答える