31

TinyMCE が選択したテキストエリアにコンテンツを挿入する場合、カーソル/キャレットの位置を設定する最良の方法は何ですか?

を使用tinyMCE.execCommand("mceInsertRawHTML", false, content);してコンテンツを挿入していますが、カーソル位置をコンテンツの最後に設定したいと思います。

document.selectionとはどちらもmyField.selectionStart機能しません。これは TinyMCE によって (フォーラムで見つけることができないものを通じて) サポートされるか、本当に醜いハックになるように感じます。

後で:良くなります。WordPress に TinyMCE をロードすると、エディタ全体が埋め込まれた iframe にロードされることがわかりました。

後で (2):選択を文字列として取得するために使用できますdocument.getElementById('content_ifr').contentDocument.getSelection();が、使用できる選択オブジェクトではありませんgetRangeAt(0)。少しずつ前進中。

4

12 に答える 12

29

最初にすべきことは、作成したいコンテンツの最後にスパンを追加することです。

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 を作成する際に使用する戦略です。基礎となるソースを読むことは、この種の問題に非常に役立ちます。

于 2010-04-25T18:48:39.483 に答える
28

この問題に 15 時間以上費やした後 (献身的であることはわかっています)、FF と Safari では機能するが IE では機能しない部分的な解決策を見つけました。現時点では、これで十分ですが、今後も作業を続ける可能性があります。

解決策: 現在のキャレット位置に HTML を挿入する場合、使用する最適な関数は次のとおりです。

tinyMCE.activeEditor.selection.setContent(htmlcontent);

Firefox と Safari では、この関数は、WordPress が TinyMCE エディターとして使用する iframe 内の現在のキャレット位置にコンテンツを挿入します。IE 7 および 8 の問題は、関数が iframe ではなくページの上部にコンテンツを追加するように見えることです (つまり、テキスト エディターが完全に見落とされます)。この問題に対処するために、IE の代わりにこの関数を使用するこのコードに基づく条件ステートメントを追加しました。

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

ただし、この 2 番目の関数の問題は、呼び出された後にキャレット位置が投稿領域の先頭に設定されることです (ブラウザーの範囲などに基づいて呼び出すことは期待できません)。最後のどこかで、この関数が最初の関数で挿入されたコンテンツの最後にキャレット位置を復元するように機能することを発見しました。

tinyMCE.activeEditor.focus();

さらに、挿入されたテキストの長さを計算することなく、挿入されたコンテンツの末尾にキャレット位置を復元します。欠点は、IE 7 および IE 8 で問題を引き起こすと思われる最初の挿入関数でのみ機能することです (これは TinyMCE よりも WordPress の障害である可能性があります)。

言葉足らずな答えですね。明確にするために、遠慮なく質問してください。

于 2009-08-18T01:27:04.837 に答える
15

カーソルを末尾に移動するのは非常に簡単なので、これを行うためにオンラインの他の場所に投稿されたひどいクラッジが信じられません. Spocke 氏の回答は最初は役に立ちませんでしたが、最終的には API ドキュメントが回答を提供してくれました。「すべてのコンテンツを選択してから選択を折りたたむ」:

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

ed.selection.collapse(false);

このスレッドは Google で最初に登場したスレッドの 1 つであるため、これが他の人の助けになることを願っています。

于 2011-11-30T01:32:19.757 に答える
8

私が見つけた最良の方法は、一時 ID を使用してコンテンツを挿入し、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 エディターにコンテンツを挿入しようとしている人にとって、これは機能するソリューションです。このページの別のスクリプト、Gary Tan による上記の回答を含む、他のスクリプトを多数試しました。これは、カスタム TinyMCE ボタンをインストールするときに機能しましたが、このシナリオでは機能しませんでした。

于 2011-03-24T03:10:15.710 に答える
6

正しい解決策は、tinyMCEapitinymce.dom.Selectionを使用することです。

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

それは私がこれを自分で使用して動作します。

于 2012-02-17T12:00:48.230 に答える
2

次のように、現在のキャレット位置に html コンテンツを挿入しています (その html 親要素にとどまることなく):

editor.insertContent( '<div>My html inserted code here...</div>' + '&nbsp;' , {format: 'html'} );

最後の空白スペースにより、さらに入力されたテキストが挿入された div 要素の外側に配置されます。

于 2019-06-19T15:28:08.463 に答える
1

現在の選択/キャレットの場所にDOMノードを挿入します。

tinyMCE.activeEditor.selection.setNode(tinyMCE.activeEditor.dom.create('img', {src : 'some.gif', title : 'some title'}));
于 2012-10-23T15:32:49.203 に答える
1

ここに自分の 2 セントを投入するだけです。これらのどれも私の質問に答えませんでした。私は HTML 要素ではなく、テキストのブロック ([code][/code]たとえば) を入れていたので、カーソルが 2 つの間に移動する必要がありました。

@robyatesの回答の一部を使用して、2つの[code]タグの間に一時的なHTML要素を配置し、それに焦点を合わせてから、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
        }
    });
}
于 2015-11-17T19:02:06.813 に答える
1

ここから 盗作 しました.

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); 
    } 
} 
于 2009-08-12T02:21:49.733 に答える
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);
}
于 2014-02-12T10:05:21.397 に答える