您应该使用keydown
事件(接近您的建议):
var editor = CKEDITOR.instances.editor1;
editor.document.getBody().on('keydown', function(event) {
if (event.data.getKeystroke() === 65 /*a*/ && isFirstLetter()) {
// insert 'A' instead of 'a'
editor.insertText('A');
event.data.preventDefault();
}
});
现在 - 应该isFirstLetter()
是什么样子?
- 您必须从
editor.getSelection().getRanges()
获得插入符号位置开始。
- 您只对集合中的第一个范围感兴趣。
- 要从插入符号之前提取文本内容,请使用小技巧:
- 将范围的开头移动到文档的开头:
range.setStartAt( editor.document.getBody(), CKEDITOR.POSITION_AFTER_START )
,
- 用于
CKEDITOR.dom.walker
按源顺序遍历 DOM 树,
- 收集文本节点并找出插入符号之前的内容(是
/\. $/
吗) - 请记住,您必须跳过内联标签并在块标签上停止 - 提示:false
从guard
函数返回以停止遍历。
如何使用walker
on的示例range
:
var range, walker, node;
range = editor.getSelection().getRanges()[0];
range.setStartAt(editor.document.getBody(), CKEDITOR.POSITION_AFTER_START);
walker = new CKEDITOR.dom.walker(range);
walker.guard = function(node) {
console.log(node);
};
while (node = walker.previous()) {}
现在很少有悲伤的事情了。
- 我们假设您键入时选择为空 - 这不一定是真的。When selection is not collapsed (empty) then you'll have to manually remove its content before calling
insertText
. 您可以使用它range#deleteContents
来执行此操作。
- 但这还不是全部 - 删除范围的内容后,您必须将插入符号放置在正确的位置 - 这不是微不足道的。基本上您可以使用
range#select
(在 之后的范围内deleteContents
),但在某些情况下,它可以将插入符号放置在不正确的位置 - 例如段落之间。如果没有关于 HTML+editables+insertions+其他东西的 deeeeeeeep 知识,解决这个问题是不可行的 :)。
- 这个解决方案并不完整——你必须处理
paste
事件、删除内容(可以从句子的开头删除单词)等等。
- 我想还有几个我什至没有想过的其他问题:P。
所以这种方法是不现实的。如果您仍想实现此功能,我认为您应该设置计时器并通过遍历 DOM(您可以walker
在包含整个文档的范围内使用,或最近键入的文本(很难找到它在哪里))找到从小写字母开始的所有句子并修复它们。