Qual è il modo migliore per impostare la posizione del cursore / cursore?

Se sto inserendo del contenuto in una textarea che TinyMCE ha cooptato, qual è il modo migliore per impostare la posizione del cursore / cursore?

Sto usando tinyMCE.execCommand("mceInsertRawHTML", false, content); per inserire il contenuto, e mi piacerebbe impostare la posizione del cursore alla fine del contenuto.

Sia document.selection che myField.selectionStart non funzioneranno per questo, e sento che questo sarà supportato da TinyMCE (attraverso qualcosa che non riesco a trovare sul loro forum) o che sarà un brutto colpo.

Più tardi: migliora Ho appena capito che, quando carichi TinyMCE in WordPress, carica l’intero editor in un iframe incorporato.

Più tardi (2): posso usare document.getElementById('content_ifr').contentDocument.getSelection(); per ottenere la selezione come stringa, ma non un object di selezione su cui posso utilizzare getRangeAt(0) . Fare progressi poco alla volta.

Innanzitutto ciò che dovresti fare è aggiungere uno span alla fine del contenuto che desideri creare.

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

Questa è una strategia utilizzata dagli sviluppatori di TinyMCE per scrivere Selection.js. Leggere la fonte sottostante può essere di grande aiuto per questo tipo di problema.

Dopo aver trascorso più di 15 ore su questo tema (dedizione, lo so), ho trovato una soluzione parziale che funziona in FF e Safari, ma non in IE. Per il momento, questo è abbastanza buono per me anche se potrei continuare a lavorarci in futuro.

La soluzione: quando si inserisce HTML nella posizione attuale del cursore, la migliore funzione da utilizzare è:

tinyMCE.activeEditor.selection.setContent(htmlcontent);

In Firefox e Safari, questa funzione inserirà il contenuto nella posizione attuale del cursore all’interno dell’iframe che WordPress utilizza come editor TinyMCE. Il problema con IE 7 e 8 è che la funzione sembra aggiungere il contenuto alla parte superiore della pagina, non all’iframe (cioè manca completamente l’editor di testo). Per risolvere questo problema, ho aggiunto un’istruzione condizionale basata su questo codice che utilizzerà questa funzione per IE:

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

Il problema di questa seconda funzione, tuttavia, è che la posizione del cursore viene impostata all’inizio dell’area del post dopo che è stata richiamata (senza alcuna speranza di richiamarla in base all’intervallo del browser, ecc.). Da qualche parte vicino alla fine ho scoperto che questa funzione funziona per ripristinare la posizione del cursore alla fine del contenuto inserito con la prima funzione:

tinyMCE.activeEditor.focus();

Inoltre, ripristina la posizione del cursore fino alla fine del contenuto inserito senza dover calcolare la lunghezza del testo inserito. Lo svantaggio è che funziona solo con la prima funzione di inserimento che sembra causare problemi in IE 7 e IE 8 (che potrebbe essere più di un errore WordPress di TinyMCE).

Una risposta prolissa, lo so. Sentiti libero di fare domande per chiarimenti.

È così semplice spostare il cursore verso la fine che non posso credere agli orribili clandestini che sono stati pubblicati altrove online per farlo. La risposta del signor Spocke non era inizialmente utile, ma alla fine i documenti API mi hanno fornito la risposta. “Seleziona tutto il contenuto e poi comprimi la selezione”:

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

Spero che questo aiuti qualcun altro in quanto questo thread è uno dei primi a venire su Google.

La soluzione corretta è usare il minuscolo MCE api tinymce.dom.Selection

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

la syntax è qualcosa come:

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

funziona io lo uso da solo.

Il modo migliore che ho trovato è quello di inserire il contenuto con un id temp e quindi concentrarsi su alcuni trucchi che ho trovato nel plugin advlink .

Spero che questo ti aiuti.

  var ed = tinyMCE.activeEditor; ed.execCommand('mceInsertContent', false, 'robubu.com'); //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 

Se lo fai da un popup penso che devi anche aggiungere

  tinyMCEPopup.storeSelection(); 

prima di chiudere il popup.

Per chiunque cerchi di inserire contenuti da una meta box personalizzata di WordPress nell’editor TinyMCE, questa è la soluzione che funziona. Ho provato un sacco di altri script, tra cui un altro in questa pagina, la risposta sopra di Gary Tan, che ha funzionato per me durante l’installazione di pulsanti personalizzati TinyMCE, ma non ha funzionato in questo scenario.

Inserire un nodo DOM nella posizione corrente di selezione / cursore.

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

Sto solo lanciando i miei 2 centesimi qui. Nessuno di questi ha risposto alla mia domanda. Non stavo inserendo un elemento HTML, ma un blocco di testo ( [code][/code] per esempio) e avevo bisogno del cursore per andare tra i due.

Usando parte della risposta @robyates, ciò che ho fatto è stato inserire un elemento HTML temporaneo tra i 2 tag [code] , focalizzarci su di esso, quindi rimuovere completamente l’elemento HTML. Ecco il mio codice:

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

L’ho plagiato da qui .

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

Quindi, ecco la soluzione dal nostro progetto. Il nostro objective era di cambiare (+)/(-)/(?) stringhe nelle immagini appropriate “al volo” mentre l’utente stava digitando.

C’è stato un problema: ogni volta dopo aver cambiato una stringa in un’immagine, il cursore è andato all’inizio dell’immagine, non alla fine come previsto.

Abbiamo aggiunto la maggior parte del codice che sposta il cursore alla fine dell’immagine, in modo che l’utente possa digitare continuamente senza interrompere il cursore “jumpy”.

Parte fondamentale: invece di utilizzare editor.getBody , esiste un modo più elegante per creare lo span temporaneo e, inoltre, eliminarlo immediatamente dopo le azioni necessarie.

 if (value.match(/\([+?-]\)/)) { // set current cursor via span editor.selection.setContent(''); // refresh Content with new span value = editor.getContent(); // changing (+)/(-)/(?) to the appropriate image "on the fly" value = value.replace('(+)', '  '); value = value.replace('(-)', '  '); value = value.replace('(?)', '  '); 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(); } 

Questa è la soluzione che funziona per me:

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