Программно выделите текст в элементе HTML contenteditable?
в 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 Level 2 см. Также MDN) и выбор, который указывается как часть новая спецификация диапазона ( MDN документы).
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, дал мне пару результатов.