1

I am creating a range based on a user selection using the following method:

var selection = window.getSelection();
var beginsAt = selection.getRangeAt(0).startOffset;
var endsAt = selection.getRangeAt(0).endOffset;
return [beginsAt,endsAt];

The component that calls this function does the following:

let before = text.substring(0, range[0]);
let highlighted = text.substring(range[0], range[1]);
let after = text.substring(range[1], text.length);
return(
        <div>
            {before}
            <span style={{
                backgroundColor: 'yellow'
            }}>
                {highlighted}
            </span>
            {after}
        </div>
)

Whenever I select my text, the range is always relative to where the highlighted span ends. So if my text is on a range between 0 and 50 and I select the range [25,26] then select the range [26,27], rather than highlighting the range [26,27] it highlights the range from [0,1] because the range was [0,1] relative to the text generated by {after}.

As long as I highlight any text rendered by {before} I have no issues, its only when I highlight something rendered in the {after} section.

How can I make these range values relative to the root of the entire text rather than relative to the blocks that they are rendered in? Is this a limitation of react or my implementation?

FactorialTime
  • 147
  • 12

2 Answers2

0

Most likely you are getting [0,1] because that is the offset in the current node. What you need is the offset within the collection of nodes in the parent node. I think this answer has what you need: https://stackoverflow.com/a/26477716/4650008

Community
  • 1
  • 1
Phil H
  • 1
  • This implementation would most certainly work however I found a more simple specific solution to suit my problem. Thank you for your input! – FactorialTime Sep 20 '16 at 01:55
0

The issue is most certainly with the implementation and not a limitation of javascript or react (at least in the way that question is proposed here).

Rather than try and force the indexes to conform to a parent container it is much easier to simply offset them based on a previous selection.

The method that gets the selection can be modified to contain the following:

(relativityFlag) => {
    var selection = window.getSelection();
    var beginsAt = selection.getRangeAt(0).startOffset;
    var endsAt = selection.getRangeAt(0).endOffset;

    if(relativityFlag){
        beginsAt += endsAt;
        endsAt += endsAt;
    }
    return [beginsAt, endsAt]
}

Where the relativity flag is true if the selection is inside of the {after} render block.

This is one of many different ways to conform the index to a greater range but is of the simplest to implement.

FactorialTime
  • 147
  • 12