这个问题问在了Stack Overflow, 但是没有得到答案, 我自己绕过去了.

insert a span, and then the keyboard input can not out of the span

  • the code target : when user press space, auto input a span, and then user can continue input,
  • when i trace them in the devtools,range.setEnd(lasttextnode, 0); and range.collapse() run in right way,
  • but the keyboard input is not right, i set the caret on the text, but input appear in span.

here is my code :

editor.onkeydown = editinput;
var sel = window.getSelection();

function editinput(e) {
  var range = sel.getRangeAt(0);

  if (e.isComposing || e.keyCode === 229) { //imk
    return;
  }
  if (e.keyCode == 32) { //space

    var tnode = range.commonAncestorContainer;
    var start = range.startOffset;
    var text = tnode.textContent;

    var span = document.createElement('span');
    span.innerHTML = '------span------';

    var firsttextnode = document.createTextNode(text.substring(0, start));
    var lasttextnode = document.createTextNode(text.substring(start));
    var fragment = new DocumentFragment();
    fragment.append(firsttextnode, span, lasttextnode);
    tnode.replaceWith(fragment);
    range.setEnd(lasttextnode, 0); // here is problem,
    range.collapse();

    e.stopPropagation(); //bubble
    e.preventDefault(); //default.
  }
}
[contenteditable=true] {
  display: inline-block;
  white-space: pre-wrap;
  width: 400px;
  height: 100%;   
}

div, textarea,   span {
  border: 1px solid rgba(122, 206, 143, 0.966);
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
<div id="editor" contenteditable="true" class="Weave" tabIndex="1">
  samelinesamelinesamelinesamelinesamelinesamelinesame
  <span>deerge span</span>oaeueouaoeu <span>disange span</span>
</div>

here is problem, the keyboard input will in span that just insert.

but if i change range.setEnd(lasttextnode, 0); to range.setEnd(lasttextnode, 1), it will run right;

i have try a lot of method:

  1. range.collapse();
  2. range.setStart(lasttextnode,0)
  3. sel.removeAllRanges();
  4. sel.collapse(lasttextnode,0)
  5. range.setStartBefore(lasttextnode);
  6. range.setStartAfter(span);

all of them is not work.

绕过去的方案

var lasttextnode=document.createTextNode(' ' + text.substring(start)); //这里加了一个空格
...... 
range.setStart(lasttextnode,1); //这里设置为后一位