Search code examples
javascriptrangy

Solution with overlapping text ranges.


I have a following problem and looking for hints how to do this with rangy or native range object. I have div element that containing following text: "This is example text." From service I receiving this example json response. [{ start: 0, end: 10}, {start: 2, end: 8}] I want to add spans that marks text from 0 to 10 and from 2 to 8. So second span - from 2 to 8 must be added with deviation of the already added span.

Best regards.


Solution

  • Rangy 1.3 has simple character offset-based getting and setting in the core via getBookmark() and moveToBookmark() methods of Range. Once you have a range you can split text nodes at the range boundaries, get all the text nodes in the range using getNodes() and surround each in turn in a span.

    Demo: http://jsfiddle.net/mL0jz0xg/

    Code:

    function highlightCharacterRange(el, start, end) {
        var range = rangy.createRange();
        range.moveToBookmark({
            containerNode: el,
            start: start,
            end: end
        });
        range.splitBoundaries();
        var textNodes = range.getNodes([3]);
        for (var i = 0, textNode, span; textNode = textNodes[i++]; ) {
            span = document.createElement("span");
            span.className = "highlight";
            textNode.parentNode.insertBefore(span, textNode);
            span.appendChild(textNode);
        }
    }
    
    var container = document.getElementById("container");
    highlightCharacterRange(container, 0, 10);
    highlightCharacterRange(container, 2, 8);
    highlightCharacterRange(container, 7, 14);