2009-08-10 13 views
27

Jeśli wstawiam treść do obszaru tekstowego, który został użyty przez TinyMCE, jaki jest najlepszy sposób ustawiania pozycji kursora/palca?Jaki jest najlepszy sposób ustawienia pozycji kursora/karetki?

Używam tinyMCE.execCommand("mceInsertRawHTML", false, content); do wstawiania treści, a ja chciałbym ustawić pozycję kursora na końcu zawartości.

Zarówno document.selection, jak i myField.selectionStart nie będą działać, i mam wrażenie, że będzie to wspierane przez TinyMCE (przez coś, czego nie mogę znaleźć na ich forum) lub będzie to naprawdę brzydki hack.

Później: Staje się lepiej; Właśnie zorientowałem się, że po załadowaniu TinyMCE w WordPress, ładuje cały edytor we wbudowanym iframe.

później (2): mogę używać document.getElementById('content_ifr').contentDocument.getSelection(); uzyskać wybór jako ciąg, ale nie obiekt do wyboru, że można używać getRangeAt(0) dalej. Robiąc postępy krok po kroku.

+0

tutaj jest lepszym odpowiedź: http://stackoverflow.com/a/7977681/3197383 –

Odpowiedz

20

Po spędzeniu ponad 15 godzin w tej sprawie (poświęcenia, wiem), znalazłem częściowe rozwiązanie, które działa w FF oraz Safari, ale nie w IE. W tej chwili jest to dla mnie wystarczająco dobre, chociaż mogę kontynuować pracę nad nim w przyszłości.

Rozwiązanie: Podczas wstawiania HTML w aktualnej pozycji karetki, najlepiej funkcji do wykorzystania jest:

tinyMCE.activeEditor.selection.setContent(htmlcontent);

W Firefoksie i Safari, ta funkcja będzie wstawić zawartość w aktualnej pozycji karetki w ramach iframe, którego WordPress używa jako edytora TinyMCE. Problem z IE 7 i 8 polega na tym, że funkcja wydaje się dodawać zawartość na górze strony, a nie element iframe (to znaczy całkowicie pomija edytor tekstu). Aby rozwiązać ten problem, dodałem warunkową deklarację based on this code że będzie używać tej funkcji zamiast IE:

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

Kwestia tej drugiej funkcji jest jednak, że pozycja daszek jest ustawiony na początku obszar postu po jego wywołaniu (bez nadziei na przywołanie go w oparciu o zakres przeglądarki itp.). Gdzieś przy końcu odkryłem, że ta funkcja działa w celu przywrócenia pozycji daszka na końcu wstawionej zawartości z pierwszej funkcji:

tinyMCE.activeEditor.focus();

Ponadto przywraca pozycję daszka do końca włożona treść bez konieczności obliczania długości wstawionego tekstu. Minusem jest to, że działa tylko z pierwszą funkcją wstawiania, która wydaje się powodować problemy w IE 7 i IE 8 (co może być bardziej błąd WordPress niż TinyMCE).

Wątpliwa odpowiedź, wiem. Zachęcamy do zadawania pytań w celu wyjaśnienia.

1

Mam plagiat ten od 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

Myślę, że dużym problemem jest to, że TinyMCE wczytuje treści w iframe w WordPressie. Normalnie coś takiego by działało, ale 'getSelection()' zwraca tylko ciąg znaków, a nie wybór. Używam .selectionStart podczas manipulowania tekstem, którego używa edytor HTML, ale nie działa dla elementu iframe TinyMCE. –

26

Najpierw powinieneś dodać rozpiętość na końcu treści, którą chcesz utworzyć.

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

Jest to strategia używana przez samych programistów TinyMCE podczas pisania Selection.js. Czytanie źródłowego źródła może być bardzo pomocne w tego typu problemach.

+0

Doskonale, dzięki! – Alex

+0

To rozwiązanie nie działało w domyślnym edytorze Wordpress, więc dodałem   w środku: '  ' i pomogło. Dzięki! – Andrius

+0

@ Garry Tan, edytowałem urywek, działa jak dla mnie. Dzięki! – Evgeny

4

Najlepszym sposobem, jaki znalazłem, jest wstawienie treści o identyfikatorze temp, a następnie nadanie jej ostrości za pomocą sztuczek znalezionych w advlink plugin.

Mam nadzieję, że to pomoże.

  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 

Jeśli robisz to z popup Chyba trzeba także dodać

 tinyMCEPopup.storeSelection(); 

przed zamknięciem okienka popup.

Dla każdego, kto próbuje wstawić zawartość z niestandardowego edytora Wordpress do edytora TinyMCE, jest to rozwiązanie, które działa. Wypróbowałem mnóstwo innych skryptów, w tym inny na tej stronie, powyższą odpowiedź Gary Tan, który pracował dla mnie podczas instalacji niestandardowych przycisków TinyMCE, ale nie działał w tym scenariuszu.

+0

Ten działa dobrze podczas pracy w ramach Wordpress. – Cleanshooter

14

Przesunięcie kursora do końca jest tak proste, że nie mogę uwierzyć, że okropne kostki zostały opublikowane w innym miejscu, aby to zrobić. Odpowiedź pana Spocka nie była początkowo pomocna, ale ostatecznie dokumenty API dostarczyły mi odpowiedzi. „Zaznacz wszystkie treści, a następnie zwinąć wybór”:

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

ed.selection.collapse(false); 

Mam nadzieję, że to pomoże ktoś jak tego wątku jest jednym z pierwszych, którzy pojawią się w Google.

+1

To nie umieszcza karetki po ostatnim elemencie, jeśli ostatni element to ul lub ol. – rpilkey

+0

działa idealnie Dzięki! – SamSerious

6

Prawidłowe rozwiązanie jest użycie tinymce.dom.Selection tinyMCE api

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

syntaxe jest coś takiego:

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

działa Używam ten sam.

+2

Czy mógłbyś wyjaśnić, co ... znaczy? Może dać przykład? – Evgeny

1

Wstaw węzeł DOM w bieżącym położeniu zaznaczenia/karetki.

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

Jest to rozwiązanie, które działa na mnie:

// 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

tylko rzucanie we własnych 2 centy tutaj. Żadne z nich nie odpowiedziało na moje pytanie. Nie wstawiałem elementu HTML, ale blok tekstu (na przykład [code][/code]) i potrzebowałem kursora, aby przejść między tymi dwoma.

Używając części odpowiedzi @robyates, wprowadziłem tymczasowy element HTML pomiędzy znacznikami 2 [code], skupiłem się na nim, a następnie całkowicie usunąłem element HTML. Tu jest mój kodu:

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 
     } 
    }); 
} 
Powiązane problemy