web-dev-qa-db-ja.com

コンテンツ編集可能なHTML要素内のテキストをプログラムで選択しますか?

JavaScriptでは、inputまたはtextarea要素のテキストをプログラムで選択できます。 ipt.focus()を使用して入力をフォーカスし、 ipt.select() を使用してその内容を選択できます。 ipt.setSelectionRange(from,to) を使用して特定の範囲を選択することもできます。

私の質問は:contenteditable要素でもこれを行う方法はありますか?

キャレットをcontenteditable要素に入れるためにelem.focus()を実行できることがわかりましたが、その後elem.select()を実行しても機能しません(およびsetSelectionRange)。私はそれについてウェブ上で何も見つけることができませんが、多分私は間違ったことを探しています...

ちなみに、違いがあれば、Google Chromeで動作する必要があるのは、これがChrome拡張機能であるためです。

101
callum

Chromeで要素のすべてのコンテンツ(コンテンツ編集可能かどうか)を選択する場合の方法は次のとおりです。これは、Firefox、Safari 3 +、Opera 9+(おそらく以前のバージョンも))およびIE 9.で動作します。必要なAPIはDOM範囲(現在の仕様は DOM Level 2 です。 [〜#〜] mdn [〜#〜] も参照してください) 新しい範囲仕様MDN docs )の一部として指定されています。

function selectElementContents(el) {
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

var el = document.getElementById("foo");
selectElementContents(el);
153
Tim Down

Tim Downs answer に加えて、oldIEでも機能するソリューションを作成しました。

var selectText = function() {
  var range, selection;
  if (document.body.createTextRange) {
    range = document.body.createTextRange();
    range.moveToElementText(this);
    range.select();
  } else if (window.getSelection) {
    selection = window.getSelection();
    range = document.createRange();
    range.selectNodeContents(this);
    selection.removeAllRanges();
    selection.addRange(range);
  }
};

document.getElementById('foo').ondblclick = selectText;​

テスト済みIE 8+、Firefox 3+、Opera 9+、&Chrome 2+。Even I've jQueryプラグインにセットアップします。

jQuery.fn.selectText = function() {
  var range, selection;
  return this.each(function() {
    if (document.body.createTextRange) {
      range = document.body.createTextRange();
      range.moveToElementText(this);
      range.select();
    } else if (window.getSelection) {
      selection = window.getSelection();
      range = document.createRange();
      range.selectNodeContents(this);
      selection.removeAllRanges();
      selection.addRange(range);
    }
  });
};

$('#foo').on('dblclick', function() {
  $(this).selectText();
});

...そして誰が興味を持っているか、ここはすべてのコーヒー中毒者に同じです:

jQuery.fn.selectText = ->
  @each ->
    if document.body.createTextRange
      range = document.body.createTextRange()
      range.moveToElementText @
      range.select()
    else if window.getSelection
      selection = window.getSelection()
      range = document.createRange()
      range.selectNodeContents @
      selection.removeAllRanges()
      selection.addRange range
    return

更新:

ページ全体または編集可能な領域のコンテンツ(contentEditableでフラグが設定されている)を選択する場合は、designModeに切り替えてdocument.execCommand

良い MDNの開始点alittledocumentation があります。

var selectText = function () {
  document.execCommand('selectAll', false, null);
};

(IE6 +で正常に動作します、Opera 9 +、Firefoy 3 +、Chrome 2+) http://caniuse.com/#search = execCommand

34
yckart

既存の回答はすべてdiv要素を扱っているため、spansを使用してそれを行う方法を説明します。

spanでテキスト範囲を選択する場合、微妙な違いがあります。テキストの開始インデックスと終了インデックスを渡すことができるようにするには、 here で説明されているように、Textノードを使用する必要があります。

StartNodeがText、Comment、またはCDATASectionタイプのNodeである場合、startOffsetはstartNodeの先頭からの文字数です。その他のNode=タイプ、startOffsetは、startNodeの開始間の子ノードの数です。

var e = document.getElementById("id of the span element you want to select text in");
var textNode = e.childNodes[0]; //text node is the first child node of a span

var r = document.createRange();
var startIndex = 0;
var endIndex = textNode.textContent.length;
r.setStart(textNode, startIndex);
r.setEnd(textNode, endIndex);

var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);
7
Domysee

Rangyでは、このクロスブラウザーを同じコードで実行できます。 Rangyは、選択のためのDOMメソッドのクロスブラウザー実装です。十分にテストされており、これにより痛みが大幅に軽減されます。私はそれなしでcontenteditableに触れることを拒否します。

あなたはここでランジーを見つけることができます:

http://code.google.com/p/rangy/

プロジェクトでrangyを使用すると、ブラウザがIE 8以前で、選択用の完全に異なるネイティブAPIを持っている場合でも、いつでもこれを記述できます。

var range = rangy.createRange();
range.selectNodeContents(contentEditableNode);
var sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);

ここで、「contentEditableNode」は、contenteditable属性を持つDOMノードです。次のように取得できます。

var contentEditable = document.getElementById('my-editable-thing');

または、jQueryが既にプロジェクトの一部であり、便利であることがわかった場合:

var contentEditable = $('.some-selector')[0];
6
Tom Boutell

[間違いを修正するために更新]

Chrome-- contenteditable div で範囲を選択してください。

var Elm = document.getElementById("myText"),
    fc = Elm.firstChild,
    ec = Elm.lastChild,
    range = document.createRange(),
    sel;
Elm.focus();
range.setStart(fc,1);
range.setEnd(ec,3);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

HTMLは次のとおりです。

<div id="myText" contenteditable>test</div>
2
patorjk