3

I got the following HTML:

<div id="editable_phrase">
   My 
   <span style="background-color: #19FC49;"> first</span> 
   <span style="background-color: #09AC20;"> first</span> //note 2 firsts here
   <span style="background-color: #D2C3EA;"> phrase</span>
</div>

And the original phrase that is - My first phrase

I need to find a position of a first letter of a selected word in my original phrase. So if I select (highlight with a mouse) phrase, I need to get 10 (or whatever it is). I tried to use charAt() or window.getSelection but still getting wrong results.

Moreover, if I select the same word but in different positions (like inm my example above where there are 2 first words) I get the same result as it finds the position of the first word while I need the second one.

I can use jQuery. Any ideas would be welcome. Thank you.

Masha
  • 827
  • 1
  • 10
  • 30
  • [This sounds like an X Y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), what are you trying to do with that position? – Hodrobond Jun 06 '17 at 17:04
  • I need to store it in DB and then apply a tag to the whole word in order to highlight – Masha Jun 06 '17 at 17:05
  • What if you highlight between two elements? (e.g. "st phra" from the example above) – Joseph Marikle Jun 06 '17 at 17:14
  • I have already implemented a function that snaps a selection to words, but anyway If I could get the position of the letter without it, it would be great – Masha Jun 06 '17 at 17:15
  • @Masha I've deleted my answer. I'll have to look into it more a little later when I have some more time. The important part was the code to highlight text. This is the question that addresses that: https://stackoverflow.com/questions/3731328/on-text-highlight-event?noredirect=1&lq=1 – Joseph Marikle Jun 06 '17 at 17:50

3 Answers3

2

As you've said you've already got a function to get selection of words, it's as simple as indexOf() - just replace the selectedText below with the word your function returns, and do the action after the text was selected:

let el = document.getElementById('editable_phrase');

let selectedText = "phrase";
let originalPhrase = el.innerText;

console.log(originalPhrase.indexOf(selectedText));
<div id="editable_phrase">
  My
  <span style="background-color: #19FC49;"> first</span>
  <span style="background-color: #D2C3EA;"> phrase</span>
</div>
baao
  • 71,625
  • 17
  • 143
  • 203
  • Looks like `innerText` is nicer than `textContent` in this context. – Joseph Marikle Jun 06 '17 at 17:24
  • It doesn't require the replacements you have in your answer.. @JosephMarikle. Your answer is a good one however, feel free to steal the innerText. :-) – baao Jun 06 '17 at 17:26
1

Here's an answer that combines baao's answer and Joseph Marikle's answer (has since been deleted).

selection.anchorNode.textContent gets the word that is being highlighted.

$("#editable_phrase").bind('mouseup', function(e) {
  var selection;
  var selectedWordPos;
  if (window.getSelection) {
    selection = window.getSelection();
  } else if (document.selection) {
    selection = document.selection.createRange();
  }
  selectedWordPos = $("#editable_phrase").text().replace(/\s\s+/g, ' ').indexOf(selection.anchorNode.textContent.replace(/\s\s+/g, ' '));
  console.log(selectedWordPos);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editable_phrase">
  My
  <span style="background-color: #19FC49;"> first</span>
  <span style="background-color: #D2C3EA;"> phrase</span>
</div>
Anthony
  • 1,439
  • 1
  • 19
  • 36
  • you are selecting the whole word, that is fine, but try to select the same letters or add the same word and check whether the result changes – Masha Jun 06 '17 at 20:25
0

iterate over the children of the div, and concat them to one string until you get to the desired value, and then return the length of it. for example, something like this: var str = "";

var bool = false;
$('#editable_phrase').children().each(function(){
    if ($(this).text() == "phrase")
        bool = true;
    if (!bool)
        str+=$(this).text();
});
LiorP
  • 94
  • 4