html - selection range - getting the range + starting node + ending node + distance

Sagar R. Kothari picture Sagar R. Kothari · Jun 2, 2010 · Viewed 20.7k times · Source

From my previous question for selecting specific html text, I have gone through this link to understand range in html string.

For selecting a specific text on html page. We need to follow this steps.

Assumed HTML:

<h4 id="entry1196"><a
    href="http://radar.oreilly.com/archives/2007/03/call_for_a_blog_1.html"
    class="external">Call for a Blogger's Code of Conduct</a></h4>

<p>Tim O'Reilly calls for a Blogger Code of Conduct. His proposals are:</p>

<ol>
    <li>Take responsibility not just for your own words, but for the
        comments you allow on your blog.</li>
    <li>Label your tolerance level for abusive comments.</li>
    <li>Consider eliminating anonymous comments.</li>
</ol>

java script to make selection by range

var range = document.createRange();  // create range
var startPar = [the p node];         // starting parameter 
var endLi = [the second li node];    // ending parameter
range.setStart(startPar,13);         // distance from starting parameter.
range.setEnd(endLi,17);              // distance from ending parameter
range.select();                      // this statement will make selection

I want to do this in invert way. I mean, assume that selection is done by user on browser (safari). My question is that How can we get starting node (as we have 'the p node' here) and ending node (as we have 'the second li node' here) and the range as well (as we have 13,17 here)?

Edit : my efforts (From this question)

    var sel = window.getSelection();

    if (sel.rangeCount < 1) {
        return;
    }
    var range = sel.getRangeAt(0);
    var startNode = range.startContainer, endNode = range.endContainer;

    // Split the start and end container text nodes, if necessary
    if (endNode.nodeType == 3) {
        endNode.splitText(range.endOffset);
        range.setEnd(endNode, endNode.length);
    }

    if (startNode.nodeType == 3) {
        startNode = startNode.splitText(range.startOffset);
        range.setStart(startNode, 0);
    }

But, yet I am confused about getting like, if selected is first paragraph or second or third, or selected is in first heading or second heading or what....

Answer

Tim Down picture Tim Down · Jun 2, 2010

Storing the selected range is simple. The following will return only the first selected range (Firefox at least supports multiple selections):

<script type="text/javascript">

function getSelectionRange() {
    var sel;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            return sel.getRangeAt(0);
        }
    } else if (document.selection) {
        return document.selection.createRange();
    }
    return null;
}

var range;

</script>
<input type="button" onclick="range = getSelectionRange();"
    value="Store selection">

range will have properties startContainer (the node containing the start of the range), startOffset (an offset within the start container node: a character offset in the case of text nodes and child offset in elements), endContainer and endOffset (equivalent behvaiour to the start properties). Range is well documented by its specification and MDC.

In IE, range will contain a TextRange, which works very differently. Rather than nodes and offsets, TextRanges are concerned with characters, words and sentences. Microsoft's site has some documentation: http://msdn.microsoft.com/en-us/library/ms533042%28VS.85%29.aspx, http://msdn.microsoft.com/en-us/library/ms535872%28VS.85%29.aspx.