2

Take the following lump of HTML:

<span id="1">The </span><span id="2">quick brown fox </span><span id="3">jumped </span><span id="4">over the lazy dog.</span>

Which rendered, just looks like:

The quick brown fox jumped over the lazy dog.

If I were to highlight a portion of the rendered text, how could I tell which elements were covered by the highlighted area? For example if I highlighted "fox jumped" then I'd want to know that it was #2 and #3 that were included.

PhonicUK
  • 13,486
  • 4
  • 43
  • 62
  • 1
    It is possibly duplicate of this:- http://stackoverflow.com/questions/5643635/how-to-get-selected-html-text-with-javascript – pvnarula Jun 11 '13 at 22:19
  • By "highlight", you mean "select"? – nnnnnn Jun 11 '13 at 22:24
  • @pvnarula - looked at that already - doesn't get me the information I need. The answers there just get you the HTML of the selected area which isn't what I want. I want the IDs of whatever tags *contain* the selection. Multiple or otherwise. – PhonicUK Jun 11 '13 at 22:30
  • @PhonicUK I added the code please check, hope it helps. it catches the textnode parent. – pvnarula Jun 11 '13 at 22:38

2 Answers2

1

Here's my attempt.. tested only in chrome and FF.

Fiddle here: http://jsfiddle.net/fdBkv/1/

HTML:

<div>
    <span id="a">wowo wheheh</span>
    <span id="b">lolol wwoww</span>
    <span id="c">hmmmmm</span>
    <span id="d">zzzzzm</span>
</div>

JS:

$(document).mouseup(function() {

    var s = window.getSelection ? window.getSelection() : document.getSelection();

    var from = $(s.anchorNode).closest('span');
    var to = $(s.focusNode).closest('span');

    var spans;
    if (from[0] === to[0])
        spans = from;
    else if (from.nextAll('span').is(to))
        spans = from.add(from.nextUntil(to)).add(to);
    else
        spans = to.add(to.nextUntil(from)).add(from);



    console.log(
        'from: ' + from.prop('id'),
        'to: ' + to.prop('id'),
         'spans: ', spans.get());

});
antishok
  • 2,910
  • 16
  • 21
0

In standard/compliant browsers:

var sel = getSelection(), range, selected = [];
if (sel.rangeCount) {
    range = sel.getRangeAt(0);
    var start = range.startContainer.parentNode,
        end = range.endContainer.parentNode;
    while (start !== end) {
        selected.push(start);
        start = start.nextSibling;
    }
    selected.push(end);
}

Note that this solution works if the selection is entirely contained in the spans, otherwise you'd have to make some additional checks about start and end (tip: compareDocumentPosition can help).

MaxArt
  • 22,200
  • 10
  • 82
  • 81