javascript-修改选择,选择单词,然后重新附加脱字号的位置

所以我想用javascript制作一个所见即所得的编辑器.我正在尝试做的是:当我没有做出选择并且只将插入符号放在一个单词上时,我想选择该单词,对其执行命令,然后将插入符号移回其位置.

例:
在执行代码之前(插入符号应位于函数之后):

使这个词变老

后:

使这个词加粗|

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);
}

解决方法:

问题是,在运行document.execCommand之后,它会立即重置范围,您可以在oldRange上执行console.log并注释掉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);
}
<button onclick="changeStyle('bold')">
  Bold
</button>
<div contentEditable=true id="editor">
Try make a word bold without make a selection, the caret will either jump to the start of the word or the end.
It should stay on its position.
</div>
上一篇:想进大厂,想收获高薪offer,资深猎头告诉你怎么做......


下一篇:Javascript:在数据库中获取和保存文本选择范围