我已经在几乎相同的问题上读到了这个优秀的答案.但是,我已经尝试了@Reinmar推荐的所有技术,但它们似乎都不起作用.
情况是我从编辑器中获取当前的HTML并将某些部分包装在span标签中.然后我将现在修改的HTML设置回来并尝试恢复用户的光标位置.没有技术可行.
这是一个重现问题的简单示例:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
</head>
<body>
<textarea id="cktest"><p>Sometimes Lorem. Sometime Ipsum. Always dolor.</p></textarea>
<script type="text/javascript">
(function () {
var checkTimeout;
var bookmark;
var storeCursorLocation = function(editor) {
bookmark = editor.getSelection().createBookmarks();
};
var restoreCursorLocation = function(editor) {
editor.getSelection().selectBookmarks(bookmark);
};
var validateText = function(editor) {
storeCursorLocation(editor);
var data = editor.document.getBody().getHtml();
data = data.replace("Lorem", "<span class='err-item'>Lorem</span>");
editor.document.getBody().setHtml(data);
restoreCursorLocation(editor);
};
CKEDITOR.replace('cktest', {
on: {
'instanceReady': function(evt) {
},
'key' : function(evt) {
clearTimeout(checkTimeout);
checkTimeout = setTimeout(function () {
validateText(evt.editor);
}, 1000);
}
}
});
})();
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
当用户按下一个键时,该代码启动一个计时器,然后在他们停止按键进行检查后等待1秒钟.
将其复制到新的.html文件并在您喜欢的浏览器中运行(我使用的是Chrome).
加载CKEditor时,使用鼠标将光标放在文本中间的某个位置.然后按CTRL键并等待1秒钟.您将看到光标跳回文本的开头.
此代码示例使用
editor.getSelection().createBookmarks();
Run Code Online (Sandbox Code Playgroud)
创建书签.但我也尝试过:
editor.getSelection().createBookmarks(true);
Run Code Online (Sandbox Code Playgroud)
和
editor.getSelection().createBookmarks2();
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用保存范围
var ranges = editor.getSelection().getRanges();
Run Code Online (Sandbox Code Playgroud)
和
editor.getSelection().selectRanges(ranges);
Run Code Online (Sandbox Code Playgroud)
在restoreCursorLocation函数中.
(function () {
var checkTimeout;
var bookmark;
var storeCursorLocation = function( editor ) {
bookmark = editor.getSelection().createBookmarks( true );
};
var restoreCursorLocation = function( editor ) {
//editor.focus();
editor.getSelection().selectBookmarks( bookmark );
};
var validateText = function( editor ) {
storeCursorLocation( editor );
var data = editor.document.getBody().getHtml();
data = data.replace( "spaceflight", "<span class='err-item'>spaceflight</span>" );
editor.document.getBody().setHtml( data );
restoreCursorLocation( editor );
//fire this event after DOM changes if working with widgets
//editor.fire( 'contentDomInvalidated' );
};
var editor = CKEDITOR.replace( 'editor1', {
extraAllowedContent : 'span(err-item)',
on: {
"pluginsLoaded" : function( event ){
editor.on( 'contentDom', function() {
var editable = editor.editable();
editable.attachListener( editable, 'keyup', function( e ) {
clearTimeout( checkTimeout );
checkTimeout = setTimeout(function () {
validateText( editor );
}, 100 );
});
});
}
}
});
})();
Run Code Online (Sandbox Code Playgroud)
我检查了你的代码,做了一些修正,上面似乎工作正常.我知道你说你已经尝试过,但对我来说createBookmarks(true)
已经做到了.
说明和注释:
createBookmarks(true)
哪些插入HTML的唯一范围.这样的书签不受您在DOM内部所做的更改的影响(当然有限制,例如您的自定义更改删除书签).getBody().getHtml()
和getBody().setHTML()
.如果你已经使用过editor.getData()
这将删除代表书签的空跨度.但请注意,此类方法可能会破坏小部件,因此需要contentDomInvalidated
在此类更改后触发事件.在这里你有一个工作的例子:http://jsfiddle.net/j_swiderski/nwbsywnn/1/