我读过这excellent answer几乎相同的问题。然而,我已经尝试了所有推荐的技术,并且它们都不起作用。CKEDITOR - 无法在DOM修改后恢复光标位置
这种情况是,我从编辑器中取出当前的HTML,并将范围内的某些片段打包成标签。然后,我将现在修改的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>
此代码,当用户按下一个键,然后等待1秒钟后,他们停止按键做检查启动定时器。
将其复制到一个新的.html文件并在您喜欢的浏览器中运行(我正在使用Chrome)。
当CKEditor加载时,使用鼠标将光标置于文本中间的某个位置。然后按下CTRL键并等待1秒钟。你会看到你的光标跳回到文本的开始处。
此代码示例使用
editor.getSelection().createBookmarks();
创建书签。但我也试过:
editor.getSelection().createBookmarks(true);
和
editor.getSelection().createBookmarks2();
我也尝试过保存在restoreCursorLocation功能使用
var ranges = editor.getSelection().getRanges();
和
editor.getSelection().selectRanges(ranges);
的范围内。
只需添加到此答案 - 一个更安全的解决方案将使用['CKEDITOR.style'](http://docs.ckeditor.com/#!/api/CKEDITOR.style),因为它只会触及必须更改的树的这些部分。但是,要使用它,您需要实现一个在DOM中查找文本的函数,这是一件非常复杂的事情。 – Reinmar
感谢Reinmar的出色答案。在真实的代码中,我使用CKEDITOR.htmlParser来浏览文档并进行修改。不只是做一个简单的.replace()。我会看看使用样式,看看它是否更好。不知道为什么createBookmark(true)以前不适合我。但现在是。 –