defend orca
defend orca

Reputation: 743

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>

when i click/keyin on the <span>deerge span</span>, the info will show all editor div. so how can i show only <span>deerge span</span> ?

Upvotes: 1

Views: 2575

Answers (2)

Kaiido
Kaiido

Reputation: 137171

document.activeElement will return the element that currently has the focus. In your case, the one element that grabs the focus is the container <div>.
You'd have to set the tabindex attribute on your <span> element for it to be focusable, but doing so in your contenteditable area is not that practical.

Instead you probably want the Range.commonAncestorContainer element, which will be the deepest Node where the current selection actually is, so in your case, where the cursor is. In case of collapsed selection, it should be the TextNode where the cursor is, you can retrieve the Element through its .parentNode property.

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>

Upvotes: 2

Anurag Srivastava
Anurag Srivastava

Reputation: 14423

Use e.target.textContent

For mouse events this works, but for keyboard events for nested contenteditable elements, you need to apply a small hack:

Set the contenteditable="true" for the span and wrap it with another span having contenteditable="false"

Check below code:

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>

Upvotes: 1

Related Questions