Каков наилучший способ установить положение курсора / курсора?
если я вставляю контент в текстовую область, которую TinyMCE кооптировал, каков наилучший способ установить положение курсора/каретки?
я использую tinyMCE.execCommand("mceInsertRawHTML", false, content);
вставить содержимое, и я хотел бы установить курсор в конец контента.
и document.selection
и myField.selectionStart
не будет работать для этого, и я чувствую, что это будет поддерживаться TinyMCE (через то, что я не могу найти на своем форуме), или это будет действительно уродливо мотыга.
позже: становится лучше; я только что понял, что, когда вы загружаете TinyMCE в WordPress, он загружает весь редактор во встроенный iframe.
позже (2): Я могу использовать document.getElementById('content_ifr').contentDocument.getSelection();
чтобы получить выбор в виде строки, но не объект выбора, который я могу использовать getRangeAt(0)
on. Постепенно продвигаюсь вперед.
10 ответов
сначала вы должны добавить промежуток в конце содержимого, которое вы хотите создать.
var ed = tinyMCE.activeEditor;
//add an empty span with a unique id
var endId = tinymce.DOM.uniqueId();
ed.dom.add(ed.getBody(), 'span', {'id': endId}, '');
//select that span
var newNode = ed.dom.select('span#' + endId);
ed.selection.select(newNode[0]);
это стратегия, используемая самими разработчиками TinyMCE при написании выбора.js. Чтение базового источника может быть массово полезно для такого рода проблем.
потратив более 15 часов на эту проблему (посвящение, я знаю), я нашел частичное решение, которое работает в FF и Safari, но не в IE. На данный момент это достаточно хорошо для меня, хотя я мог бы продолжить работу над этим в будущем.
решение: при вставке HTML в текущей позиции курсора, лучшая функция для использования:
tinyMCE.activeEditor.selection.setContent(htmlcontent);
В Firefox и Safari эта функция вставит содержимое в текущую позицию курсора внутри iframe, который WordPress использует в качестве редактора TinyMCE. Проблема с IE 7 и 8 заключается в том, что функция, похоже, добавляет содержимое в верхнюю часть страницы, а не iframe (т. е. полностью пропускает текстовый редактор). Чтобы решить эту проблему, я добавил условное утверждение на основе этого кода который будет использовать эту функцию вместо IE:
tinyMCE.activeEditor.execCommand("mceInsertRawHTML", false, htmlcontent);
проблема для этой второй функции, однако, заключается в том, что позиция курсора установлена в начале поста область после того, как она была вызвана (без надежды на ее отзыв на основе диапазона браузера и т. д.). Где-то ближе к концу я обнаружил, что эта функция работает для восстановления позиции каретки в конце вставленного содержимого с первой функцией:
tinyMCE.activeEditor.focus();
кроме того, он восстанавливает положение курсора до конца вставленного содержимого без необходимости вычисления длины вставленного текста. Недостатком является то, что он работает только с первой функцией вставки что, похоже, вызывает проблемы в IE 7 и IE 8 (что может быть больше вины WordPress, чем TinyMCE).
многословный ответ, я знаю. Не стесняйтесь задавать уточняющие вопросы.
так просто переместить курсор в конец, что я не могу поверить, что ужасные kludges, которые были размещены в другом месте в интернете, чтобы сделать это. Ответ г-на Spocke не было изначально полезны, но в конце концов описании API дал мне ответа. "Выберите все содержимое, а затем сверните выделение":
ed.selection.select(ed.getBody(), true); // ed is the editor instance
ed.selection.collapse(false);
Я надеюсь, что это поможет кому-то еще, так как этот поток является одним из первых в Google.
правильное решение-использовать для TinyMCE API-интерфейс для TinyMCE.дом.Выбор
http://www.tinymce.com/wiki.php/API3:class.tinymce.dom.Selection
синтаксис-это что-то вроде :
var rng = tinymce.DOM.createRng(); // the range obj
var newNode = editor.dom.select(... // find the correct selector so that newNode is the element of your editor text
rng.setStart(newNode.firstChild, 0); // 0 is the offset : here it will be at the beginning of the line.
rng.setEnd(newNode.firstChild, 0);
editor.selection.setRng(rng);
это работает, я использую это сам.
лучший способ, который я нашел, - вставить содержимое с идентификатором temp, а затем дать этот фокус, используя некоторые хитрости, которые я нашел в плагин advlink.
надеюсь, что это помогает.
var ed = tinyMCE.activeEditor;
ed.execCommand('mceInsertContent', false, '<a id="_mce_temp_rob" href="http://robubu.com">robubu.com</a>');
//horrible hack to put the cursor in the right spot
ed.focus(); //give the editor focus
ed.selection.select(ed.dom.select('#_mce_temp_rob')[0]); //select the inserted element
ed.selection.collapse(0); //collapses the selection to the end of the range, so the cursor is after the inserted element
ed.dom.setAttrib('_mce_temp_rob', 'id', ''); //remove the temp id
Если вы делаете это из всплывающего окна, я думаю, вам также нужно добавить
tinyMCEPopup.storeSelection();
перед закрытием всплывающего окна.
для тех, кто пытается вставить содержимое из пользовательского мета-окна Wordpress в Редактор TinyMCE, это решение, которое работает. Я пробовал тонну других сценариев, в том числе другой на этой странице, Ответ выше Гэри Тана, который работал для меня при установке пользовательских кнопок TinyMCE, но не работал в этом сценарии.
вставьте узел DOM в текущее местоположение выбора / каретки.
tinyMCE.activeEditor.selection.setNode(tinyMCE.activeEditor.dom.create('img', {src : 'some.gif', title : 'some title'}));
просто бросаю свои собственные 2 цента здесь. Никто из них не ответил на мой вопрос. Я не вставлял HTML-элемент, а блок текста ([code][/code]
например) и нужен курсор между двумя.
используя часть ответа @robyates, я поставил временный HTML-элемент между 2 [code]
теги, сосредоточьтесь на нем, затем полностью удалите элемент HTML. Вот мой код:
setup : function(ed) {
// Add a custom button
ed.addButton('codeblock', {
title : 'Code Block',
text : '[code/]',
icon: false,
onclick : function() {
// Add you own code to execute something on click
ed.focus();
//ed.selection.setContent('[code][/code]');
ed.execCommand('mceInsertContent', false, '[code]<span id="_cursor" />[/code]');
ed.selection.select(ed.dom.select('#_cursor')[0]); //select the inserted element
ed.selection.collapse(0); //collapses the selection to the end of the range, so the cursor is after the inserted element
ed.dom.remove('_cursor'); //remove the element
}
});
}
я списал это из здесь.
function setCaretTo(obj, pos) {
if(obj.createTextRange) {
/* Create a TextRange, set the internal pointer to
a specified position and show the cursor at this
position
*/
var range = obj.createTextRange();
range.move("character", pos);
range.select();
} else if(obj.selectionStart) {
/* Gecko is a little bit shorter on that. Simply
focus the element and set the selection to a
specified position
*/
obj.focus();
obj.setSelectionRange(pos, pos);
}
}
Итак, вот решение из нашего проекта. Нашей целью было изменить (+)/(-)/(?)
строки для соответствующих изображений "на лету" во время ввода пользователем.
возникла проблема: каждый раз после смены строки на изображение курсор шел в начало изображения, а не в конец, как ожидалось.
мы добавили большую часть кода, который перемещает курсор в конец изображения, поэтому пользователь может вводить непрерывно без прерывания на "нервном" курсоре.
ключевые части: Вместо использования editor.getBody
, есть более элегантный способ, чтобы создать временной промежуток и кроме того, удалить его сразу после необходимых действий.
if (value.match(/\([+?-]\)/)) {
// set current cursor via span
editor.selection.setContent('<span id="temp-span"/>');
// refresh Content with new span
value = editor.getContent();
// changing (+)/(-)/(?) to the appropriate image "on the fly"
value = value.replace('(+)', ' <img src="https://url_here/static/task_manager/img/add.png"> ');
value = value.replace('(-)', ' <img src="https://url_here/static/task_manager/img/forbidden.png"> ');
value = value.replace('(?)', ' <img src="https://url_here/static/task_manager/img/help_16.png"> ');
if (this.state.editor) {
editor.setContent(value);
// move cursor to the latter span
var newNode = editor.dom.select('span#temp-span');
editor.selection.select(newNode[0]);
editor.selection.setContent('');
}
// and refreshing content again w/o span
value = editor.getContent();
}
Это решение, которое работает для меня:
// params:
// $node: jquery node with tinymce loaded
// text: text to set at then before caret
function setTextAndCaretToEnd($node, text) {
var ed = window.tinyMCE.get($node.attr("id"));
ed.focus();
ed.selection.setContent(text);
}