在内容可编辑的段落中存在的粗体元素内设置插入符号(光标)

setting caret (cursor) inside bold element present inside contenteditable paragraph

我一直在尝试构建一个基于网络的文本编辑器。作为该过程的一部分,我正在尝试动态创建和修改基于元素的事件和用于字体编辑的击键事件。在这个特定的 jsfiddle 示例中,我试图在按下 CTRL+b 并在强元素内设置 focus/caret 时创建一个强元素,以便随后输入的文本将成为粗体元素的一部分,因此将有粗体字。但是我的代码只是创建了一个强大的元素,而不是转移焦点,因此没有文本变得更粗。

在下面的代码中,我正在创建事件侦听器来捕获击键事件

p=document.getElementsByTagName("p")[0];

//console.log(p)

// adding eventlistener for keydown
p.addEventListener("keydown",listener);

// eventlistenerr callback function
function listener(){
  e=window.event;
  if(e.ctrlKey && e.keyCode==66)
    {
      console.log("CTRL+B");

      // creating bold element
      belm=document.createElement("strong");
      belm.setAttribute("contenteditable","true")
      p.appendChild(belm);

      //bug below
      // setting focus inside bold element
      setfocus(belm,0);
      e.preventDefault();
    }
}

这里是设置焦点的函数

function setfocus(context, position){
    var range = document.createRange();
    position =position || 0;
    var sel = window.getSelection();
    range.setStart(context, position);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    context.focus();
}

但是,我并不怀疑设置焦点的函数有问题,因为在 fiddle 如果你观察,我已经创建了一个单独的设置来测试这个 出去。单击按钮 "Click Here",焦点会毫不费力地动态转移到段落元素。我无法弄清楚出了什么问题。

几乎不可能将光标移动到 contenteditable div 中的空元素中。然而,正如 shay levi 在另一个 post 中建议的那样,您可以将零宽度字符 &#200B 插入到空元素中以给它一个索引值。

这是一个例子*:

function insertNode(nodeName) {
  var sel = window.getSelection(),
    range;
  range = sel.getRangeAt(0);
  range.deleteContents();

  var child = document.createElement(nodeName);
  child.innerHTML = '​';
  range.insertNode(child);
}

var div = document.querySelector('div'),
  btn = document.querySelector('button');

btn.addEventListener('click', function() {
  insertNode('strong');
  div.focus();
});

div.focus();
<div contenteditable></div><button><strong>B</strong></button>

*为了简单起见,此脚本不会切换粗体文本,它只会设置它。