plugins - 插入不可编辑元素后的CKEditor光标位置

标签 plugins insert cursor ckeditor range

我在开发 CKEditor 插件时遇到了麻烦,这些插件将不可编辑的内容插入到文本流中。我一直在尝试利用范围函数,但收效甚微,因为文档不够完善。因此,给定一些文本,假设插件插入“[[uneditable stuff]]”,然后在 WYSIWYG 显示中将其包装在一个跨度中,以便可以用颜色设置样式:
<p>This is some text[[uneditable stuff here]]</p>
当第一次插入不可编辑的内容时,我们希望用户能够继续输入或按 Enter 键换行。以下代码(我在这里得到的: How to set cursor position to end of text in CKEditor? )适用于 Firefox,但(自然地)不适用于 IE9、8 或 7:

var s = editor.getSelection();
editor.insertElement(e); // element 'e'= a span created earlier
var p = e.getParent();
s.selectElement(p);
var selected_ranges = s.getRanges();
selected_ranges[0].collapse(false);  //  false = to the end of the selected node
s.selectRanges(selected_ranges);  // putting the current selection there

所以我想要发生的是光标位于“^”位置:
<p>This is some text<span>[[uneditable stuff here]]</span>^</p>
如果新元素不在行尾,则创建后,光标应转到此处:
<p>This is some text<span>[[uneditable stuff here]]</span>^ with more text after the new element</p>
在 FF 中,我可以在行尾获取光标,但不在新元素之后的位置。在 IE 中,光标仍然在新的 SPAN 内,我在输入时看到它并且它仍然是跨度的 css 颜色,当切换到源 View 时,文本消失了(因为它是一个不可编辑的跨度)。

我知道有一个 range.setStartAfter 方法,但即使在 FF/Chrome 中也完全无法使其工作。

有人对在 CKEditor 中使用范围和选择方法有很好的掌握吗?我知道我没有!

开始认为只使用 editor.insertElement 是错误的,我应该了解 FakeElement (insertBogus?) 函数,但我还不明白。链接和图像等库存插件似乎没有这个问题。

最佳答案

我不得不做一些偷偷摸摸的事情来解决这个问题,但它确实得到了解决:在创建不可编辑的项目(具有属性 content-editable: false 的跨度)之后,我必须创建一个“虚拟”跨度,文本由一个空格组成.所以,我插入了真实的跨度,然后是虚拟的。但仅在创建新项目时。

所以这在“如果不处理编辑所选项目”部分。这里,'a' 是编辑器实例,'e' 是所需的不可编辑项,'f' 是虚拟跨度。

var e=new CKEDITOR.dom.element('span',a.document);
e.setAttributes({// stuff to create our element});
var f=new CKEDITOR.dom.element('span',a.document);
f.setAttributes({
    'class':'dummyF'
});
f.setText(' '); // that's just one space

// after section dealing with editing a selected item, in "else":
var sel = a.getSelection(); // current cursor position
a.insertElement(e); // the real new element
if(CKEDITOR.env.ie || CKEDITOR.env.webkit){ // IE & Chrome like this way
    f.insertAfter(e);
    sel.selectElement(f);
}
else { //FF likes this way (to ensure cursor stays in the right place)
    f.insertAfter(e);
    var rangeObjForSelection = new CKEDITOR.dom.range( a.document );
    rangeObjForSelection.selectNodeContents( f );
    a.getSelection().selectRanges( [ rangeObjForSelection ] );
}

我不得不承认我并不完全理解我自己的代码。我经过数小时的反复试验才到达那里。哦,我不得不添加一个 htmlFilter 规则来摆脱剩余的 'f' 元素:
e.addRules({
  // e is the htmlFilter: applied to editor data before/upon output
  elements:{
    span:function(s){ // 's' is any spans found in the editor
        if(s.attributes&&s.attributes['data-cke-myelement']) {
            //stuff to do with my element
        }
        else if(s.attributes['class']=='dummyF') { //CKEDITOR.env.ie&&
            // for dummy spans to deal with "can't type or hit enter after new element" problem
            realtext = new String(s.children[0]['value']);
            realtext.replace(/^&nbsp;/,'');
            s.children[0]['value'] = realtext;
            delete s.name;
        }
    }
  }
});

我还必须补充一点,我不记得为什么在删除跨度之前必须替换“nbsp”实体。但它有效。而且我不知道为什么要删除您使用“s.name”而不仅仅是“s”。

希望能帮助某人。

关于plugins - 插入不可编辑元素后的CKEditor光标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8914543/

相关文章:

ruby-on-rails - 创建包含 Rails 模型的 gem

c++ - 我应该使用 CFPlugin 还是 dlopen() 作为 OSX 上的 C++ 插件

java - 调用返回游标的存储函数

java - 将数据从 Cursor 绑定(bind)到 Spinner Android

javascript - jquery.flot.dashes.js 与 windows firefox 兼容吗?

wordpress - 在 WordPress 中以强大的形式单击提交按钮后显示弹出窗口

asp.net - DetailsView/FormView 是否足够丰富以进行编辑和插入?

mysql - 使用 linq 模板插入不返回 id - MySQL

php - 通过php从textarea字段的每一行插入数据库

qt - QGraphicsItem - 跟随鼠标光标