document.activeElement 无法获取目标元素

document.activeElement can not get target element

editor.onmouseup = editclick;
editor.onkeydown=editinput;
function editclick(e) {
  info.innerHTML += '<br>' + document.activeElement.textContent
}
function editinput(e) {
  info.innerHTML += '<br>' + document.activeElement.textContent
}
<div id="editor" contenteditable="true" class="" tabIndex="1">
  <span>diyige span</span> saosuoasueousameli
</div>
<div id="info"></div>

当我 click/keyin 在 <span>deerge span</span> 上时,信息将显示所有编辑器 div。那我怎么才能只显示 <span>deerge span</span> 呢?

使用e.target.textContent

对于鼠标事件,这是可行的,但对于嵌套 contenteditable 元素的键盘事件,您需要应用一个小技巧:

span 设置 contenteditable="true" 并用另一个具有 contenteditable="false"

span 包裹它

检查以下代码:

editor.onmouseup = editclick;
editor.onkeypress = editKey;

function editclick(e) {
  info.innerHTML += '<br>' + e.target.textContent
}

function editKey(e) {
  info.innerHTML += '<br>' + e.target.textContent
}
body {
  background: #fff;
}
<div id="editor" contenteditable="true" class="" tabIndex="0">
  <span contenteditable="false">
    <span contenteditable="true">contenteditable span</span>
  </span><br/>
  contenteditable div content comes here. contenteditable div content comes here.
</div>
<div id="info"></div>

document.activeElement 将 return 当前具有 焦点 的元素。在您的情况下,抓住焦点的一个元素是容器

.
您必须在 元素上设置 tabindex 属性才能使其可聚焦,但在 contenteditable 区域中这样做并不实用。

相反,您可能需要 Range.commonAncestorContainer 元素,这将是当前选择实际所在的最深节点,因此在您的情况下,光标所在的位置。在折叠选择的情况下,它应该是光标所在的TextNode,您可以通过其.parentNode 属性.

检索Element

editor.onmouseup = editclick;
editor.onkeydown=editinput;
function editclick(e) {
  let focus_elem = getElemAtCursor();
  info.innerHTML += '<br>' + focus_elem.textContent;
}
function editinput(e) {
  const focus_elem = getElemAtCursor();
  info.innerHTML += '<br>' + focus_elem.textContent;
}

function getElemAtCursor() {
 const elem = getSelection().getRangeAt(0).commonAncestorContainer;
 return elem.nodeType === 1 ? elem : elem.parentNode;
}
<div id="editor" contenteditable="true" class="">
  <span>diyige span</span> saosuoasueousameli
</div>
<div id="info"></div>