0

I want to check if currently highlighted/selected text parent has class using JS/jQuery

Ex :

<div class="foo">
    <div> This text is selected with the cursor </div>
</div>

I tried :

if (document.getSelection().parents('.foo').length) {
       console.log("parent has class foo!");
}

But this is obviously not a valid solution since document.getSelection().parents is not a function

azthorgis
  • 37
  • 8
  • Get the `anchorNode` of the Selection object first, that is the node in which the selection begins - and then check what parents _that_ has? (You’ll still have to wrap `$(…)` around the DOM node reference, to be able to call jQuery’s `parents` method.) – CBroe Jun 25 '21 at 08:28

3 Answers3

3

You can get the selected text with

window.getSelection();

this has .anchorNode and .focusNode properties which contains the (text) node that is selected (depending on what exactly is selected)

See .anchorNode vs .focusNode for the difference.

Giving snippet below. Note, I've used mouseup just to be able to test selecting without changing the focus/selection. Using mouseup would already let you know which element was selected. OP didn't include how/when their code was to be run, so this just allows a demonstration of the code.

$(document).on("mouseup", () => {

var parent = $(window.getSelection().focusNode).closest("div");
if (parent.is(".foo"))
    console.log("parent has class foo!");
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo">
    <p> Select with the mouse </p>
</div>
<div class="notfoo">
    <p> Select with the mouse </p>
</div>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
  • Thanks ! My only issue with this is that my text is wrapped in a div and not in p (sorry, my mistake). So the closest('div') function is being sabotaged – azthorgis Jun 25 '21 at 08:42
  • To summarize I'm building a WYSIWYG component which has 2 windows. When I write some text, this is what's rendered in the DOM :
    Some text
    and the parent div is the main frame of the window. I need to check if this frame as a certain class to determine in which frame I am
    – azthorgis Jun 25 '21 at 08:51
  • I'd suggest giving *both* your potential parents the same class, then each a different class, eg `
    ...
    ..
    ` then use `.closest("div.frame").is(".markup")`.
    – freedomn-m Jun 25 '21 at 09:01
  • unfortunately I can't change parents classes because these divs are generated by a JS library I don't fully understand. But I figured out the solution and your first shot helped me a lot. Thanks! – azthorgis Jun 25 '21 at 09:07
  • Ah, I misread your comment above - thought you said it was in a `p` not a `div`, – freedomn-m Jun 25 '21 at 09:07
  • You could do `$("div.foo").addClass("frame")`, no need to change the html – freedomn-m Jun 25 '21 at 09:10
  • Or you could do `if (...closest("div.foo").length === 1) ..` – freedomn-m Jun 25 '21 at 09:10
0

A vanilla JS solution could be:

function checkCSSClass(el, className) {
  return el.classList.contains(className);
}

document.addEventListener('mouseup', () => {
  const parentEl = document.getSelection().focusNode.parentElement.parentElement;
  console.log('has foo class?: ', checkCSSClass(parentEl, 'foo'));
  console.log('has bar class?: ', checkCSSClass(parentEl, 'bar'));
});
<div class="foo">
  <div>This text is selected with the cursor </div>
</div>
secan
  • 2,622
  • 1
  • 7
  • 24
0

Got what I wanted, using a part of @freedomn-n 's solution

$(window.getSelection().focusNode).closest("div").offsetParent().hasClass('foo');
azthorgis
  • 37
  • 8