21

Is it possible to get the parent element of a selected text in the page? For example:

<div class="someparent">

Selection of this text should refer to the 'someparent' class.

<span class="spanparent">If this is selected, the parent should be this span</span>

</div>

Because when getting the selected text, it normally gets it from the window or the document (depending on the browser) but is it that possible to get the parent element of the selected text?

Saksham
  • 9,037
  • 7
  • 45
  • 73
MacMac
  • 34,294
  • 55
  • 151
  • 222

3 Answers3

54

Here's a function that will get you the innermost element that contains the whole of the user selection in all major browsers (except when multiple ranges are selected, which is only supported in Firefox. If this is important, I can expand the example to deal with that case too):

function getSelectionParentElement() {
    var parentEl = null, sel;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            parentEl = sel.getRangeAt(0).commonAncestorContainer;
            if (parentEl.nodeType != 1) {
                parentEl = parentEl.parentNode;
            }
        }
    } else if ( (sel = document.selection) && sel.type != "Control") {
        parentEl = sel.createRange().parentElement();
    }
    return parentEl;
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
14

I'd suggest to use this

window.getSelection().anchorNode.parentElement

I have tested in safari osx 10.9

chintan adatiya
  • 1,233
  • 14
  • 17
  • -1, when i selection is made, many nodes can be selected together and anchorNode or focusNode any of them can be higher in DOM tree (depending on selection direction and length). One should get a parent that is covering both anchorNode and focusNode. – Praveen Tiwari Feb 08 '18 at 03:53
  • This work perfectly on my part... – Jenuel Ganawed Dec 18 '22 at 12:44
2

@Tim Down's answer works good, to add more useful code for reaching the specific parent's html content:

function getSelectionParentElement() {
  var parentEl = null, sel;
  if (window.getSelection) {
      sel = window.getSelection();
      if (sel.rangeCount) {
          parentEl = sel.getRangeAt(0).commonAncestorContainer;
          if (parentEl.nodeType != 1) {
              parentEl = parentEl.parentNode;
          }
      }
  } else if ( (sel = document.selection) && sel.type != "Control") {
      parentEl = sel.createRange().parentElement();
  }
  while(true){
      // I want to reach upper <span> parent
      if(parentEl.nodeName == "SPAN"){
          console.log(parentEl);
          break;
      }
      else{
          parentEl = parentEl.parentNode;
      }
  }
}

For example:

function getSelectionParentElement() {
      var parentEl = null, sel;
      if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
              parentEl = sel.getRangeAt(0).commonAncestorContainer;
              if (parentEl.nodeType != 1) {
                  parentEl = parentEl.parentNode;
              }
          }
      } else if ( (sel = document.selection) && sel.type != "Control") {
          parentEl = sel.createRange().parentElement();
      }
      while(true){
          // I want to reach upper <span> parent
          if(parentEl.nodeName == "P"){
              document.getElementById("printable").innerText = parentEl.innerHTML;
              break;
          }
          else{
              parentEl = parentEl.parentNode;
          }
      }
    }
<head>
    <style type="text/css">
    @media print
    {
        #non-printable { display: none; }
        #printable { display: block; }
    }
    </style>
</head>

<p>The <strong>coronavirus</strong> COVID-19 is affecting <strong>210 <i>countries</i> and territories</strong> around the world and 2 international conveyances.</p>

<div id="printable">Output: </div>
<button onclick="getSelectionParentElement()">Select 'countries' and click me.</button>
ATES
  • 281
  • 1
  • 11
  • 29