msqar
msqar

Reputation: 3020

Get current node within text selection in javascript

I'm attempting to get the node I'm standing at after selecting the text meaning if I have the following DOM structure:

<p>
   This is an example
   <span style="text-transform: uppercase">text in caps</span>
   some more text in here
</p>

When I select text in caps, i would like to get the node where this selection is. In this case, would be the <span> in case I select everything of course.

I know there's a library called rangy but I think it's kinda overkill for me to use it just to get these nodes, any other way to retrieve it?

This is how I implement it so far:

var select = window.getSelection();
if (select.rangeCount) {
   var $elem = $('<span>', {'style': 'text-transform: ' + type});
   var range = select.getRangeAt(0).cloneRange();
   var selectedNode = range.cloneContents().childNodes[0];
   var nodeHasStyle = !!(selectedNode.style && selectedNode.style.textTransform.length !== 0);

   if (nodeHasStyle) {
       // If it's the same as previous, just toggle it by resetting the node
       var currentStyle = selectedNode.style.textTransform;
       selectedNode.style.textTransform = currentStyle === type ? '' : type;
   }

   range.surroundContents(!nodeHasStyle ? $elem.get(0) : selectedNode);

   select.removeAllRanges();
   select.addRange(range);

But noticed selectedNode is not always correct. So whenever I do surroundContents, it adds a new span around the one that I should have gotten in the first place.

I'm working with summernote to toggle uppercase, lowercase text-transform over a range of selected text.

Any help would be appreciated.

Thanks.

Upvotes: 1

Views: 1289

Answers (1)

Aimal Khan
Aimal Khan

Reputation: 449

you do not need to rely on other libraries first you need to get the selected text then find node which contained this text through xpath i.e

let text = window.getSelection().toString()
if (text) {
  let xpath = "//text()[contains(., '"+ text +"')]";
  let selectionNode = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

or you can use window selection i.e window.getSelection().anchorNode.parentNode

Upvotes: 2

Related Questions