如果我将内容插入到TinyMCE已经选择的文本区中,那么设置光标/插入符位置的最佳方法是什么?
我正在使用tinyMCE.execCommand("mceInsertRawHTML", false, content);
插入内容,我想将光标位置设置为内容的结尾。
document.selection
和myField.selectionStart
都不适用于此,我觉得TinyMCE会支持(通过我在论坛上找不到的东西),或者它会继续是一个非常难看的黑客。
后来:它变得更好;我刚才发现,当您在WordPress中加载TinyMCE时,它会将整个编辑器加载到嵌入式iframe中。
稍后(2):我可以使用document.getElementById('content_ifr').contentDocument.getSelection();
将选择作为字符串,但不能使用getRangeAt(0)
上的选择对象。一点一点地取得进步。
答案 0 :(得分:27)
首先,您应该在要创建的内容的末尾添加一个范围。
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时使用的策略。阅读基础资源可以极大地帮助解决这类问题。
答案 1 :(得分:23)
在这个问题上花了超过15个小时(奉献,我知道),我找到了一个部分解决方案,适用于FF和Safari,但不适用于IE。目前,这对我来说已经足够好了,尽管我将来可能继续努力。
解决方案:在当前插入位置插入HTML时,最好使用的功能是:
tinyMCE.activeEditor.selection.setContent(htmlcontent);
在Firefox和Safari中,此功能会将内容插入到WordPress用作TinyMCE编辑器的iframe中的当前插入位置。 IE 7和8的问题在于该函数似乎将内容添加到页面顶部,而不是iframe(即它完全错过了文本编辑器)。为了解决这个问题,我添加了一个条件语句based on this code,它将使用此函数代替IE:
tinyMCE.activeEditor.execCommand("mceInsertRawHTML", false, htmlcontent);
然而,第二个函数的问题是,在调用后,将插入符号位置设置为发布区域的开头(不希望根据浏览器范围调用它等)。在接近结尾的地方,我发现这个函数可以用第一个函数恢复插入内容末尾的插入位置:
tinyMCE.activeEditor.focus();
此外,它将插入位置恢复到插入内容的末尾,而不必计算插入文本的长度。缺点是它只适用于第一个插入功能,它似乎在IE 7和IE 8中引起问题(可能比TinyMCE更像是一个WordPress故障)。
我知道,这是一个罗嗦的回答。请随意提出问题以便澄清。
答案 2 :(得分:15)
将光标移动到最终是如此简单,以至于我无法相信已经在网上其他地方发布的可怕的kludges来做到这一点。 Spocke先生的回答最初并没有帮助,但最终API文档为我提供了答案。 “选择所有内容,然后折叠选择”:
ed.selection.select(ed.getBody(), true); // ed is the editor instance
ed.selection.collapse(false);
我希望这可以帮助其他人,因为这个帖子是最早出现在谷歌中的人之一。
答案 3 :(得分:6)
我找到的最好方法是插入带有temp id的内容,然后使用我在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编辑器的人来说,这是可行的解决方案。我尝试了大量其他脚本,包括本页面上的另一个脚本,上面的答案是Gary Tan,在安装自定义TinyMCE按钮时对我有用,但在这种情况下没有用。
答案 4 :(得分:6)
正确的解决方案是使用tinyMCE api tinymce.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);
它有效我自己用它。
答案 5 :(得分:2)
因此,这是我们项目的解决方案。我们的目标是在用户打字时将(+)/(-)/(?)
字符串“动态”更改为适当的图像。
有一个问题:每次将字符串更改为图片后,光标都移到图片的开头,而不是按预期的结尾。
我们添加了大量代码,将光标移动到图像的末尾,因此用户可以连续输入而不会在“跳跃”光标上打断。
关键部分:除了使用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();
}
答案 6 :(得分: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);
}
}
答案 7 :(得分:1)
在当前选择/插入符号位置插入DOM节点。
tinyMCE.activeEditor.selection.setNode(tinyMCE.activeEditor.dom.create('img', {src : 'some.gif', title : 'some title'}));
答案 8 :(得分:1)
在这里投入我自己的2美分。这些都没有回答我的问题。我没有放入一个HTML元素,而是一个文本块(例如[code][/code]
)并且需要光标在两者之间。
使用@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
}
});
}
答案 9 :(得分: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);
}
答案 10 :(得分:0)
我要在当前插入符号位置插入html内容(不留在该html父元素中),如下所示:
editor.insertContent( '<div>My html inserted code here...</div>' + ' ' , {format: 'html'} );
末尾的空格将确保将进一步键入的文本放置在插入的div元素之外。
答案 11 :(得分:0)
在Tiny版本5中
editor.selection.setCursorLocation(editor.getBody(), editor.getBody().childElementCount);