3

Take a look at the snippet of code in an HTML page below--

<div id="div2"> Text2 </div>

Now, user selects only "Te" from the text shown in web page in browser...

How do I check if the user has selected entire content of div with id=div2?

I do understand how to get list of nodes corresponding to content selected by the user-- but in this case, since user has selected only "Te" --- only a single node is obtained - i.e. text node that contains text "Te"... Hence I am confused...

What is the easiest way to check if user selection comprises of an entire Div (or p for that matter)?

One more question is if user has selected content of multiple divs, then how do I check if each of those (multiple) divs' entire content has been selected?

For example take a look at HTML snippet below--

 <div id="div1"> Text1 </div>
 <div id="div2"> Text2 </div>
 <div id="div3"> Text3 </div>

Here, user has selected text of all 3 divs above...

Finally, if user has selected content of multiple divs, all of which are within a single parent div, then how do I check if the user has selected entire content of that parent div, or only some content? The parent div may contain other divs, p elements, and images and links too...

I dont mind using pure js, or libraries like jquery for this purpose...

j08691
  • 204,283
  • 31
  • 260
  • 272
Arvind
  • 6,404
  • 20
  • 94
  • 143

4 Answers4

2

I've ended up with this but it may not the perfect one, just give it a try, may be it will give you some idea or may be someone else can make it better

function getSelectedText()
{
    var t = '';
   if(window.getSelection) t = window.getSelection();
   else if(document.getSelection) t = document.getSelection();
   else if(document.selection) t = document.selection.createRange();  
   if(t)
   { 
       return {
           selectedText:t.text ? t.text : t.toString(),
           fullContent:t.anchorNode ? t.anchorNode.nodeValue : t.parentElement().innerHTML
      };
    }
}


$(function(){
    $(document).on('mouseup', function(){
        var selection=getSelectedText();
        if(selection.selectedText)
        {
            var selected = $.trim(selection.selectedText);
            var full = $.trim(selection.fullContent);
            if(selected!=full) alert('Full content is not selected');
            else alert('Full content is selected');
         }
    });
});

DEMO.

The Alpha
  • 143,660
  • 29
  • 287
  • 307
  • `document.getSelection` is deprecated; I don't know any cases when you would have `document.getSelection` but not `window.getSelection`. See http://help.dottoro.com/ljqxhfte.php. – ZachB Aug 05 '12 at 23:43
  • Nice, the solution works even if the drag-selection mouse up event occurs outside the frame, or outside the browser. – makerofthings7 Aug 05 '12 at 23:48
  • Thank you guys, I was not just trying to answer the question but I was also trying to learn so if someone have a better idea please share or you can edit it if you can make this really better. it'll help me too. Thanks! – The Alpha Aug 05 '12 at 23:59
  • @ZachB: I'm pretty sure an old-ish version of Safari (2? 3.0?) had `document.getSelection()` but not `window.getSelection()`, along with various deficiencies in the selection object. Certainly Safari 3.2 has `window.getSelection()` and a working selection object, so it's not really a concern now. However, `document.getSelection()` isn't deprecated: it's just an alias to `window.getSelection()`. http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#dom-window-getselection – Tim Down Aug 06 '12 at 09:02
  • @TimDown Thanks for clarifying that! I mistook Mozilla and Netscape's deprecation as W3C's deprecation. – ZachB Aug 06 '12 at 22:15
1

My Rangy library provides a containsNodeText() method of its Range objects that is not part of the DOM Range standard. It looks as though this would help with all your questions.

var div2 = document.getElementById("div2");
var sel = rangy.getSelection();
var divTextIsSelected = false;
if (sel.rangeCount) {
    divTextIsSelected = sel.getRangeAt(0).containsNodeText(div2);
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
0

How about this for your first question?

window.getSelection().focusNode.nodeValue === window.getSelection()

Note that focusNode is the element containing the end of the selection, and anchorNode is the element containing the start of the selection.

In the second question, you can try traversing the DOM upward with something like

window.getSelection().getRangeAt(0).commonAncestorContainer

The getRangeAt(0) retrieves the first range of contiguous, selected element containers. (You'd have more than one if the user did a ctrl+select sort of thing.)

Here are some cases:

  • window.getSelection().getRangeAt(0).startOffset === 0 if all of the first element is selected.
  • window.getSelection().getRangeAt(0).endOffset === window.getSelection().getRangeAt(0).endContainer.length if all of the last element is selected.

If you want to explicitly check each element, check out how elements are traversed in this post: Get all DOM block elements for selected texts

Community
  • 1
  • 1
ZachB
  • 13,051
  • 4
  • 61
  • 89
  • what if there are 3 divs, user selects part of text within first div, then entire content of second div, and then part of text within 3rd div-- in this case, how do I determine that user has selected entire content of second div, but only parts of text of first and third div? Also, can you provide a solution that uses the nodes containing user selection ? as that is what I am starting with...thanks... – Arvind Aug 05 '12 at 23:04
  • @Arvind, what do you mean "a solution that uses the nodes containing user selection ?" ? `window.getSelection()` is the user's current selection; do you mean something different than that? – ZachB Aug 05 '12 at 23:13
  • @ZachB- i am sorry, i didnt go through your solution carefully before my previous comment-- you are using the user's selection.. the only query i have left is how to tackle the scenario i mentioned in my previous message (i.e. 3 divs- parts of 1st and 3rd div and full text of second div is selected by the user)... – Arvind Aug 05 '12 at 23:16
  • @Arvind, changed the original code slightly and added some more tips. If your range is contiguous (which it should be), then checking the start and end offsets only should be sufficient to know that all of the nodes between are selected. – ZachB Aug 05 '12 at 23:38
0

I made this example for you, take a look:

Live DEMO: http://jsfiddle.net/oscarj24/FsZcV/

Oscar Jara
  • 14,129
  • 10
  • 62
  • 94
  • The OP asked for a way to tell if the selected text is the same as all the text in the div. All this does is alert the selected text? – ZachB Aug 05 '12 at 23:48