获取光标插入符所在的所选 contenteditable 元素的子元素的 ID

Get ID of selected contenteditable element's child where cursor caret is located

我目前正在尝试使用 contenteditable div 创建一个编辑器,但我遇到了一个问题,即在开头单击 child-2 中的退格键会导致合并child-1child-2 在一起,这违背了它自己的目的。

我正在使用以下函数查找当前插入符位置:

caret: function() {
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt) return sel.getRangeAt(0).startOffset;
    }
    return null;
}

它一直运行良好,但要解决合并问题,我需要找出当前选择的元素并将该数据与插入符位置一起使用以使用 event.preventDefault() 并停止潜在的合并。

这是我正在使用和谈论的框架:

<div id="parent" contenteditable="true">
  <div id="child-1">
    One
  </div>
  <div id="child-2">
    Two
  </div>
  <div id="child-3">
    Three
  </div>
</div>

为了找到选定的元素,我试过这个:

console.log(document.activeElement);

查看是否打印出所选子项的ID,虽然这会将整个父元素输出到控制台,而不仅仅是 ID。

您可以将 tabindex="0" 应用于子元素,这使它们可聚焦,这将 select 使用 document.activeElement 时的子元素(否则它总是具有焦点的父元素) :

console.log(document.activeElement);
<div id="parent" contenteditable="true">
  <div id="child-1" tabindex="0">
    One
  </div>
  <div id="child-2" tabindex="0">
    Two
  </div>
  <div id="child-3" tabindex="0">
    Three
  </div>
</div>

评论后:我正在添加这个片段的屏幕截图:我点击了单词 "Two":您可以看到该行周围的虚线边框指示焦点状态:

使用Event Delegation可以轻松找到点击的节点。还可以添加其他事件,例如键和鼠标。

详情在demo中评论

演示

// Refernce the parent of all of the target nodes
var parent = document.getElementById('parent');
// Register the click event to #parent
parent.addEventListener('click', idNode);

// This is the callback that is invoked on each click
function idNode(e) {
  /* If the node clicked (e.target) is not the 
  || the registered event listener 
  || (e.currentTarget = #parent)
  */
  if (e.target !== e.currentTarget) {
    // Get the #id of clicked node
    var ID = e.target.id;
    // Reference e.target by its #id
    var child = document.getElementById(ID);

  }
  // Log the #id of each e.target at every click
  console.log('The caret is located at ' + ID);
  
  // Return the e.target as a DOM node when needed
  return child;

}
<div id="parent" contenteditable="true">
  <div id="child-1">
    One
  </div>
  <div id="child-2">
    Two
  </div>
  <div id="child-3">
    Three
  </div>
</div>