Place tags around specific text within context-sensitive text without moving the cursor

I am working on a simple word processor (I thought). It uses content. I have a list of words that I always want to highlight.

<article contenteditable="true" class="content"> <p>Once upon a time, there were a couple of paragraphs. Some things were <b>bold</b>, and other things were <i>italic.</i></p> <p>Then down here there was the word highlight. It should have a different color background.</p> </article> 

So basically I need a way to wrap a word in <span> tags. It turned out to be harder than I expected.

Here is what I tried first:

 var text = document.querySelector('article.content').innerHTML start = text.indexOf("highlight"), end = start + "highlight".length; text = text.splice(end, 0, "</span>"); text = text.splice(start, 0, "<span>"); document.querySelector('article.content').innerHTML = text; 

It uses the splice method found here .

And he does exactly what I need for this, with one big problem: the cursor moves. Since all text is replaced, the cursor loses its place, which is not very convenient for a text editor.

I also tried a couple of times using document.createRange , but the problem is, given that the start and end points of the range contain only visible characters, text.indexOf("highlight") gives an index, including tags, etc.

A few ideas I'm not sure how to implement:

  • Find out where the cursor is and place it there again after using the code above
  • Find the difference in indexes between createRange and indexOf
  • Perhaps you already have a library with such functionality that I simply cannot find

Thank you for your help!

+1
javascript html5 text cursor-position contenteditable
source share
1 answer

Firstly, I would recommend against doing this by manipulating innerHTML . This is inefficient and error prone (think about where the content contains an element with a class "highlight", for example). Here is an example of this, using DOM methods to directly control text nodes:

stack overflow

Maintaining a carriage position can be achieved in several ways. You can use a character offset approach, which has some disadvantages due to the absence of line breaks, implied <br> and blocks, but is relatively simple. Alternatively, you can use the save and restore module of my favorite Rangy library, which may be redundant for your needs, but the same approach may be used.

Here is an example of using the first approach:

http://jsbin.com/suwogaha/1

0
source share

All Articles