Программно выбрать текст в элементе contenteditable HTML?
в JavaScript можно программно выбрать текст в input
или textarea
элемент. Вы можете сфокусировать ввод с помощью ipt.focus()
, а затем выберите его содержание с ipt.select()
. Вы даже можете выбрать определенный диапазон с ipt.setSelectionRange(from,to)
.
мой вопрос: есть ли способ, чтобы сделать это contenteditable
элемент?
я обнаружил, что могу сделать elem.focus()
, поставить каретку в contenteditable
элемент, но впоследствии работает elem.select()
не работает (и не setSelectionRange
). Я не могу найти ничего в интернете об этом, но, возможно, я ищу не ту вещь...
кстати, если это имеет значение, мне нужно только работать в Google Chrome, так как это для расширения Chrome.
6 ответов
Если вы хотите выбрать все содержимое элемента (contenteditable или нет) в Chrome, вот как. Это также будет работать в Firefox, Safari 3+, Opera 9+ (возможно, и в более ранних версиях) и IE 9. Можно также создавать выборки вплоть до уровня символов. API, которые вам нужны, - это диапазон DOM (текущая спецификация DOM Уровень 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);
кроме Тим Даунс ответ, Я сделал решение, которое работает даже в 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+. Даже я установил его в плагин 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 и a littledocumentation.
var selectText = function () {
document.execCommand('selectAll', false, null);
};
(хорошо работает в IE6+, Opera 9+, Firefoy 3+, Chrome 2+)http://caniuse.com/#search=execCommand
стройный позволяет сделать это кросс-браузер с тем же кодом. 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" - это узел DOM, который имеет атрибут contenteditable. Вы можете принести его так:
var contentEditable = document.getElementById('my-editable-thing');
или если jQuery уже является частью вашего проекта, и вам это удобно:
var contentEditable = $('.some-selector')[0];
так как все существующие ответы на сделку с div
элементы, я объясню, как это сделать с span
s.
существует тонкая разница при выборе текстового диапазона в span
. Чтобы иметь возможность передавать начальный и конечный индекс текста, вы должны использовать Text
узел, как описано здесь:
если startNode является узлом типа Text, Comment или CDATASection, тогда startOffset - это количество символов с начала startnode приведена. Для других типов узлов 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);
[Исправлена ошибка]
вот пример, который адаптирован из этого ответа, который, похоже, хорошо работает в 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>
contenteditable
- Это просто атрибут, который интерпретируется браузером. Такие элементы можно изменять с помощью обычных функций DOM.
посмотреть javascript TextRanges.
кстати, быстрый поиск в SO, дал мне пару результатов.