<br> 插入 contenteditable span 无法移动光标

pob*_*oby 5 javascript firefox contenteditable

我希望所有文本和中断都在跨度中,下面的代码就是这样做的。在 IE11 和 chrome 中完美运行,但在 FF 中存在严重问题。也就是说,如果输入的第一个键是<enter>,则光标无法移动到插入的<br>之后。当输入的下一个键位于下一行时,插入符号位置似乎移动,但闪烁的光标没有移动。此外,如果使用退格键删除字符,光标将返回到第一行。

最简单的演示方法:http : //jsfiddle.net/jd2d7n3L/20/

  1. 使输入的第一个字符 < enter >
  2. 预期结果(这是在 chrome 和 IE10+ 中发生的情况)是闪烁的光标向下移动一行。
  3. 输入“a”,然后退格。预期结果是闪烁的光标在第 2 行的最左边

我在 SO 上阅读了许多与此相关的类似问题和答案,但没有一个专门处理这种情况。我怎样才能让 FF 表现得更好?

HTML

<div id=bE contenteditable="true"><br></div>
Run Code Online (Sandbox Code Playgroud)

JS

bE.addEventListener("keypress",KP);
bE.addEventListener("keypress",KU);

function getContainer()
  {
  var eC=window.getSelection().getRangeAt(0).endContainer;
  while(eC&&eC.nodeType==3)eC=eC.parentNode;
  return eC
  }

function insertElement(E)
  {
  var sel=window.getSelection(),range=sel.getRangeAt(0);
  range.deleteContents(); 
  range.collapse(true);
  range.insertNode(E);
  range.setStartAfter(E);
  range.collapse(true);
  sel.removeAllRanges();
  sel.addRange(range);     
  }

function KP(e)
  {
  var kc=e.which||e.keyCode;
  if(e.charCode||e.which===13)
    {
    var sel=window.getSelection(),range=sel.getRangeAt(0);
    var eC=getContainer();
    if(eC===bE)
      {
      eC=document.createElement("span");
      range.insertNode(eC);
      range.selectNodeContents(eC);
      sel.removeAllRanges();
      sel.addRange(range);
      }
    if(kc===13)insertElement(document.createElement("br"));
    else       insertElement(document.createTextNode(String.fromCharCode(kc)));

    e.preventDefault();
    }
  }

function KU(e) //ensures last element is br
  {
  if(!bE.lastChild||bE.lastChild.nodeName.toLowerCase()!=="br")bE.appendChild(document.createElement("br"))
  }
Run Code Online (Sandbox Code Playgroud)

pob*_*oby 3

好吧,我终于成功了。Firefox 似乎不喜欢将 <br> 作为任何父节点的最后一个子节点。如果您将一个空文本节点附加到每个尾随<br>,它就可以工作!如果 < br > 是最后一个子节点,则 Firefox 不会在 < br > 之后移动插入符号。