Hm isn’t that a lot like what you had asked here a couple of months ago? Here’s the gist of the code pen from that thread:
/**
* Helper to conveniently iterate a tree walker
*
* @param {TreeWalker} walker
* @returns {IterableIterator}
*/
function iterateWalker (walker) {
return {
[Symbol.iterator] () {
return this
},
next () {
const value = walker.nextNode()
return { value, done: !value }
}
}
}
/**
* Get the text nodes contained in a given range
*
* @param {Range} range
* @returns {Text[]}
*/
function getSelectedNodes (range) {
const walker = document.createTreeWalker(
range.commonAncestorContainer.parentElement,
NodeFilter.SHOW_TEXT,
{
acceptNode (node) {
return range.intersectsNode(node)
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT
}
}
)
return [...iterateWalker(walker)]
}
/**
* Test if a given node has some actual
* text other than whitespace
*
* @param {Node} node
* @returns {boolean}
*/
function hasText (node) {
return /\S/.test(node.textContent)
}
document.addEventListener('mouseup', () => {
const selection = window.getSelection()
const range = selection.getRangeAt(0)
const selectedNodes = getSelectedNodes(range).filter(hasText)
// Do something with the selected nodes...
console.log(selectedNodes)
})