2009-08-10 3 views
27

Если я вставляю содержимое в текстовое поле, которое TinyMCE кооптировал, как лучше всего установить положение курсора/каретки?Каков наилучший способ установки положения курсора/каретки?

Я использую tinyMCE.execCommand("mceInsertRawHTML", false, content); для вставки содержимого, и я бы хотел установить позицию курсора в конец содержимого.

document.selection Как и myField.selectionStart не будет работать для этого, и я чувствую, что это будет поддерживаться TinyMCE (через что-то я не могу найти на их форуме) или он будет очень некрасиво хак.

Позже: Все становится лучше; Я просто понял, что при загрузке TinyMCE в WordPress он загружает весь редактор во встроенный iframe.

Позже (2): я могу использовать document.getElementById('content_ifr').contentDocument.getSelection();, чтобы получить выбор в виде строки, а не объект выбора, который я могу использовать getRangeAt(0) дальше. Прогресс постепенно.

+0

Вот лучший ответ: http://stackoverflow.com/a/7977681/3197383 –

ответ

20

Проведя более 15 часов по этому вопросу (преданность, я знаю), я нашел частичное решение, которое работает в FF и Safari, но не в IE. На данный момент это достаточно хорошо для меня, хотя я могу продолжить работу над этим в будущем.

Решение: При вставке HTML в текущей позиции курсора, лучшие функции использовать это:

tinyMCE.activeEditor.selection.setContent(htmlcontent);

В Firefox и Safari, эта функция будет вставлять содержимое в текущей позиции курсора в пределах iframe, который WordPress использует как редактор TinyMCE. Проблема с IE 7 и 8 заключается в том, что функция, похоже, добавляет контент в начало страницы, а не iframe (то есть полностью пропускает текстовый редактор). Чтобы решить эту проблему, я добавил условный оператор based on this code, который будет использовать эту функцию вместо для IE:

tinyMCE.activeEditor.execCommand("mceInsertRawHTML", false, htmlcontent);

Вопрос для этой второй функции, однако, является то, что позиция каретки устанавливается в начале после того, как он был вызван (без надежды напомнить его на основе диапазона браузера и т. д.). Где-то ближе к концу я обнаружил, что эта функция работает, чтобы восстановить позицию курсора в конце вставленного содержимого с первой функцией:

tinyMCE.activeEditor.focus();

Кроме того, она восстанавливает позицию курсора до конца вставленного без необходимости вычислять длину вставленного текста. Недостатком является то, что он работает только с первой функцией вставки, которая, похоже, вызывает проблемы в IE 7 и IE 8 (что может быть скорее ошибкой WordPress, чем TinyMCE).

А словесный ответ, я знаю. Не стесняйтесь задавать вопросы для уточнения.

1

Я плагиатом это от here.

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); 
    } 
} 
+2

Я думаю, что большая проблема в том, что TinyMCE загружает содержимое в плавающем фрейме в WordPress. Обычно что-то подобное работает, но 'getSelection()' возвращает строку, а не выбор. Я использую .selectionStart при манипулировании текстовым полем, который использует редактор HTML, но он не работает для iframe TinyMCE. –

26

Прежде всего, нужно добавить промежуток в конец содержимого, которое вы хотите создать.

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 при написании Selection.js. Чтение базового источника может быть очень полезным для этой проблемы.

+0

Отлично, спасибо! – Alex

+0

Это решение did'n работало в редакторе Wordpress по умолчанию, поэтому я добавил   внутри span: '  ', и это помогло. Благодаря! – Andrius

+0

@Garry Tan, я отредактировал фрагмент, работает как для меня. Благодаря! – Evgeny

4

Лучший способ, который я нашел, - это вставить содержимое с идентификатором temp, а затем сфокусировать его, используя некоторые обманки, которые я нашел в advlink plugin.

Надеюсь, это поможет.

  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, но не работал в этом сценарии.

+0

Это хорошо работает при работе в пределах Wordpress. – Cleanshooter

14

Это настолько просто перемещать курсор до конца, что я не могу поверить в ужасные kludges, которые были опубликованы в другом месте в Интернете, чтобы сделать это. Ответ г-на Спок не был изначально полезен, но в конце API-документы предоставили мне ответ. «Выбрать все содержимое, а затем свернуть выбор»:

ed.selection.select(ed.getBody(), true); // ed is the editor instance 

ed.selection.collapse(false); 

Я надеюсь, что это помогает кто-то еще, как эта нить является одним из первых, чтобы прийти в Google.

+1

Это не помещает каретку после последнего элемента, если последний элемент является ul или ol. – rpilkey

+0

отлично работает Спасибо! – SamSerious

6

Правильное решение заключается в использовании TinyMCE API tinymce.dom.Selection

http://www.tinymce.com/wiki.php/API3:class.tinymce.dom.Selection

syntaxe что-то вроде:

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

это работает Я использую это сам.

+2

Не могли бы вы прояснить, что означает ...? Может быть, привести пример? – Evgeny

1

Вставьте узел DOM в текущее местоположение выбора/каретки.

tinyMCE.activeEditor.selection.setNode(tinyMCE.activeEditor.dom.create('img', {src : 'some.gif', title : 'some title'})); 
0

Это решение, которое работает для меня:

// 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); 
} 
1

Просто бросать в моих собственных 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 
     } 
    }); 
} 
Смежные вопросы