所以我试图在javascript中创建一个所见即所得的编辑器。我试图做的是:当我没有做出选择并且只有一个单词的插入符号时,我想选择单词,在其上执行命令然后将插入符号移回其位置。 / p>
实施例: 在我执行代码之前(插入符号应该在我的函数之后):
将这个词改为b | old
后:
将这个词设为粗体 |
jsFiddle示例:jsFiddle
到目前为止我的代码:
if (window.getSelection && (sel = window.getSelection()).modify) {
doc.focus(); // the editor
var range = sel.getRangeAt(0);
var oldRange = document.createRange();
oldRange.setStart(range.startContainer, range.startOffset);
oldRange.setEnd(range.endContainer, range.endOffset);
sel.collapseToStart();
sel.modify("move", "forward", "character");
sel.modify("move", "backward", "word");
sel.modify("extend", "forward", "word");
document.execCommand(command, false, value);
// Restore selection, Dosen't work as I expected
sel.removeAllRanges();
sel.addRange(oldRange);
}
答案 0 :(得分:2)
问题在于,运行ldconfig
后,它会立即重置范围,您可以在document.execCommand
上执行console.log并注释掉oldRange
行以进行确认。保存旧范围的唯一方法是序列化它,就像我在下面的示例中所做的那样。看看
document.execCommand
changeStyle = function(command) {
var sel;
var doc = document.getElementById('editor');
if (window.getSelection && (sel = window.getSelection()).modify) {
doc.focus();
var range = sel.getRangeAt(0);
var oldRange = saveCaret(doc);
sel.collapseToStart();
sel.modify("move", "forward", "character");
sel.modify("move", "backward", "word");
sel.modify("extend", "forward", "word");
document.execCommand(command, false, null);
// Restore selection, well, it isn't restoring it
restoreCaret(doc, oldRange)
}
}
saveCaret = function(container) {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(container);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
};
};
restoreCaret = function(container, position) {
var charIndex = 0, range = document.createRange();
range.setStart(container, 0);
range.collapse(true);
var nodeStack = [container], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && position.start >= charIndex && position.start <= nextCharIndex) {
range.setStart(node, position.start - charIndex);
foundStart = true;
}
if (foundStart && position.end >= charIndex && position.end <= nextCharIndex) {
range.setEnd(node, position.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
答案 1 :(得分:1)
对于将来可能会偶然发现此问题的任何人,实现起来并不是那么简单-主要是由于跟踪和操纵插入符号的困难。另外,跨浏览器的行尾也是任何尝试实现的问题的原因。
但是,jquery.caret在启用插入符号信息和操纵方面做得很好,因此请考虑将其检出。