admin管理员组文章数量:1334290
I am building a CMS system, where I use jQuery and CKEditor for editing content inline. When an editor is blurred, the user is requested to confirm that he/she wants to discard the edits. If 'no' is chosen, the blur event should be cancelled and the editor retain focus without changing the cursor position. Since it seems to me that this is not possible, I try to refocus the editor after the blur is done. The following code snippet is from the blur event handler:
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();
}
Note that the focus
call is done on the editor instance contained in $this.data('editor')
, but the result seems to be the same as if I do it directly on $this
.
The problem with this solution is that although it reintroduces focus, the cursor is now positioned at the beginning of the text, which is very unintuitive and annoying to the end user, who thought nothing changed. On the other hand, just giving up focus is not an option, since I would not like the user to be able to prevent resetting content and then go on to make other changes, thinking that the changes are persisted.
Therefore I would like a solution, where I can either prevent the blur altogether, or reintroduce the cursor at it's last position.
I am building a CMS system, where I use jQuery and CKEditor for editing content inline. When an editor is blurred, the user is requested to confirm that he/she wants to discard the edits. If 'no' is chosen, the blur event should be cancelled and the editor retain focus without changing the cursor position. Since it seems to me that this is not possible, I try to refocus the editor after the blur is done. The following code snippet is from the blur event handler:
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();
}
Note that the focus
call is done on the editor instance contained in $this.data('editor')
, but the result seems to be the same as if I do it directly on $this
.
The problem with this solution is that although it reintroduces focus, the cursor is now positioned at the beginning of the text, which is very unintuitive and annoying to the end user, who thought nothing changed. On the other hand, just giving up focus is not an option, since I would not like the user to be able to prevent resetting content and then go on to make other changes, thinking that the changes are persisted.
Therefore I would like a solution, where I can either prevent the blur altogether, or reintroduce the cursor at it's last position.
Share Improve this question asked Mar 30, 2013 at 13:08 bisgardobisgardo 4,6405 gold badges34 silver badges45 bronze badges2 Answers
Reset to default 5Native solutions (via window.getSelection()...
) are unsafe since browsers implement this API in different ways or/and with bugs. The problem is that "standards" for selection system, ranges and contenteditable (in general) are very poor, blurry and neglected. CKEditor bypasses these issues (many kLOC) and keeps things portable and predictable thanks to its own API.
So don't reinvent the wheel and go ahead with this code (tested in latest Chrome and 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
}
} );
If you mix this code with cached data check (editor.getData()
), you can easily avoid confirm()
when nothing has really changed:
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();
} );
I'm not sure if it works with CKEditor, but with a textarea for example you can get the current cursor position by using:
var cursor = window.getSelection().getRangeAt(0).startOffset;
In this questions there's a jQuery function: Cursor position in a textarea (character index, not x/y coordinates)
Setting the cursor on the right spot would be the same as selection a specific part of the text, more info here: Highlight text range using JavaScript
I guess it needs a little bit of thinking since CKEditor most likely will replace the textarea.
本文标签: javascriptRefocus CKEditor at correct cursor positionStack Overflow
版权声明:本文标题:javascript - Refocus CKEditor at correct cursor position - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742370623a2462165.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论