以编程方式选择可疑的HTML元素中的文本?

时间:2011-05-26 13:16:13

标签: javascript selection contenteditable

在JavaScript中,可以通过编程方式选择inputtextarea元素中的文字。您可以使用ipt.focus()关注输入,然后使用ipt.select()选择其内容。您甚至可以使用ipt.setSelectionRange(from,to)选择特定范围。

我的问题是:有没有办法在contenteditable元素中执行此操作?

我发现我可以elem.focus()将插入符号放在contenteditable元素中,但随后运行elem.select()不起作用(setSelectionRange也不行) 。我在网上找不到任何关于它的东西,但也许我正在寻找错误的东西......

顺便说一句,如果它有所不同,我只需要它在谷歌浏览器中工作,因为这是Chrome扩展。

7 个答案:

答案 0 :(得分:150)

如果您想在Chrome中选择元素的所有内容(是否可信),请按照以下步骤操作。这也适用于Firefox,Safari 3 +,Opera 9+(也可能是早期版本)和IE 9.您还可以创建字符级别的选择。您需要的API是DOM范围(当前规范是DOM Level 2,另请参阅MDN)和选择,它被指定为new Range specMDN docs)的一部分。< / p>

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);

答案 1 :(得分:34)

Tim Downs answer之外,我提出的解决方案甚至可以在o​​ldIE中使用:

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+和&amp ;;中测试Chrome 2+。甚至我已将其设置为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来更简单地执行此操作:< / p>

有一个很好的starting point at MDNa littledocumentation

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

(适用于IE6 +,Opera 9 +,Firefoy 3 +,Chrome 2+)http://caniuse.com/#search=execCommand

答案 2 :(得分:6)

Rangy允许您使用相同的代码执行此跨浏览器。 Rangy是用于选择的DOM方法的跨浏览器实现。它经过了充分的测试,使得它不那么痛苦。没有它,我拒绝接触。

你可以在这里找到rangy:

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];

答案 3 :(得分:6)

由于所有现有答案都涉及div元素,因此我将解释如何使用span s。

span中选择文字范围时会有细微差别。为了能够传递文本的开始和结束索引,您必须使用Text节点,如here所述:

  

如果startNode是Text,Comment或CDATASection类型的节点,   然后startOffset是从一开始的字符数   的StartNode。对于其他Node类型,startOffset是child的数量   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);

答案 4 :(得分:5)

现代的做事方式就是这样。有关MDN

的更多详细信息

document.addEventListener('dblclick', (event) => {
  window.getSelection().selectAllChildren(event.target)
})
<div contenteditable="true">Some text</div>

答案 5 :(得分:2)

[更新以修复错误]

以下是根据此答案改编的示例,该示例在Chrome中效果很好 - Select range in 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>

答案 6 :(得分:-6)

contenteditable只是一个属性,由浏览器解释。您可以使用普通的DOM函数修改这些元素。

请参阅javascript TextRanges

顺便说一句,在SO中快速搜索,给了我couple results