我正在构建一个CMS系统,我使用jQuery和CKEditor来内联编辑内容。当编辑器模糊时,要求用户确认他/她想要丢弃编辑。如果选择“否”,则应取消模糊事件,编辑器保持焦点而不更改光标位置。因为在我看来这是不可能的,所以我尝试在模糊完成后重新聚焦编辑器。以下代码段来自blur事件处理程序:
var $this = $(this);
if (confirm('Discard your changes?')) {
$this.html($this.data('previous'));
} else {
// Optimally prevent the blur event, but alternatively
// reintroduce focus at correct position...
$this.data('editor').focus();
}
请注意,focus
调用是在$this.data('editor')
中包含的编辑器实例上完成的,但结果似乎与我在$this
上直接执行的操作相同。
这个解决方案的问题在于,尽管它重新引入焦点,但光标现在位于文本的开头,这对于最终用户来说是非常不直观和恼人的,他们认为没有任何改变。另一方面,放弃焦点不是一种选择,因为我不希望用户能够阻止重置内容,然后继续进行其他更改,并认为更改是持久的。
因此我想要一个解决方案,我可以完全阻止模糊,或者将光标重新引入它的最后位置。
答案 0 :(得分:5)
原生解决方案(通过window.getSelection()...
)不安全,因为浏览器以不同方式或/和错误实现此API。问题在于选择系统的“标准”,范围和可信度(通常)非常差,模糊和被忽视。 CKEditor绕过了这些问题(许多kLOC),并通过自己的API保持可移植性和可预测性。
所以不要重新发明轮子并继续使用此代码(在最新的Chrome和IE10中测试):
var editor = CKEDITOR.instances.editor1;
editor.on( 'blur', function() {
console.log( 'Editor blurred.' );
var range = editor.getSelection().getRanges()[ 0 ]; // store the selection
if ( confirm( 'Discard your changes?' ) ) {
console.log( 'Changes discarded.' );
} else {
editor.focus(); // focus the instance again
range.select(); // restore previous selection
}
} );
如果您将此代码与缓存数据检查(editor.getData()
)混合使用,则可以在没有真正更改的情况下轻松避免confirm()
:
var editor = CKEDITOR.instances.editor1, cached;
editor.on( 'blur', function() {
console.log( 'Editor blurred.' );
var range = editor.getSelection().getRanges()[ 0 ]
if ( editor.getData() != cached && confirm( 'Discard your changes?' ) ) {
console.log( 'Changes discarded.' );
} else {
editor.once( 'focus', function( event ) {
event.cancel(); // cancel the *very next* event, nothing will be cached
}, null, null, 0 );
editor.focus();
range.select();
}
} );
editor.on( 'focus', function() {
console.log( 'Cached editor contents.' );
cached = editor.getData();
} );
答案 1 :(得分:0)
我不确定它是否适用于CKEditor,但是以textarea为例,您可以使用以下方法获取当前光标位置:
var cursor = window.getSelection()。getRangeAt(0).startOffset;
在这个问题中有一个jQuery函数:Cursor position in a textarea (character index, not x/y coordinates)
将光标设置在右侧位置与选择文本的特定部分相同,更多信息请参见:Highlight text range using JavaScript
我想这需要一点点思考,因为CKEditor最有可能取代textarea。