Native Dev
Native Dev

Reputation: 7392

Get all elements in selection/highlight using window.getSelection

I can get a single element, or common ancestor element, but I can't figure out how to get all elements that are being highlighted.

Here's a demo of getting the common ancestor.

console.clear();
document.querySelector('div').addEventListener('mouseup', () => {
  const selection = window.getSelection();
  const elem = selection.getRangeAt(0).commonAncestorContainer.parentNode;
  console.log(elem);
});
<div contenteditable="true">
  <header>
    <h1>Rich Text Editing Development</h1>
    <p>I'm <strong><em>really</em> annoyed</strong> with trying to figure out this answer.</p>
  </header>
</div>

Since rangeCount is always only 1, and the objects I see from selection and other children don't have an array or nodeList of selected items (that I noticed), I don't know what to do.

So how do I know which elements are being selected/highlighted?

Upvotes: 3

Views: 3437

Answers (2)

Jakub Wawszczyk
Jakub Wawszczyk

Reputation: 376

In case anyone needs text nodes, you can use the accepted answer with a small tweak:

...
const elements = range.cloneContents().childNodes;
...

Otherwise when just a text node is selected, querySelectorAll will return an empty list.

Upvotes: 0

Native Dev
Native Dev

Reputation: 7392

Though you'll get a copy of the descendant elements instead of references to the real ones, you can use the cloneContents() method of a Range, in addition to the common ancestor parent node (even supported in IE11 if using ES5 syntax):

document.addEventListener('mouseup', () => {
  
  console.clear();
  
  const selection = window.getSelection();
  if (!selection.rangeCount) return;
  
  const range = selection.getRangeAt(0);
  
  console.log('Selected elements:');
  range.cloneContents().querySelectorAll('*').forEach(e => console.log(e));
  
  console.log('Selected text/elements parent:');
  console.log(range.commonAncestorContainer.parentNode);

});
<div contenteditable="true">
  <header>
    <h1>Rich Text Editing Development</h1>
    <p>I'm <strong><em>really</em> annoyed</strong> with trying to figure out this answer.</p>
  </header>
</div>

Upvotes: 9

Related Questions