To get the text we use textContent
... What I do is capture the text that is shown inside the div
, and then separate it by spaces with a regular expression /[\b\s\n]+/gi
, then I reassign the content of div
, but this time converted to words with span
.
The problem with assigning the content again is that the position of the cursor is lost ... For this you can make a function that changes the cursor.
Note: In my example, the cursor does not work completely well, it seems to be teleporting ... At the end of the day, it's just a demonstration.
To add spaces at the end of the word I do <a> </a>
. Although I could have added only one space by innerHTML
, I recommend using appendChild
... For the same reason, the cursor returns to the beginning, because I am using innerHTML
, and also, determine the position when there are several <span>
mixed in the HTML structure is a complicated task.
To make it notice that it is grouped in span
, I put a background of another color in each word.
function asignar_posición(div,posición)
{
var range = document.createRange()
var sel = window.getSelection()
range.setStart(div, posición)
range.collapse(true)
sel.removeAllRanges()
sel.addRange(range)
}
function obtener_posición_final_selección() {
return document
.defaultView.getSelection()
.getRangeAt(0).startOffset
}
document.getElementById('test').addEventListener('keyup', function(e) {
var test = document.querySelector("#test")
var texto = document.querySelector("#test").textContent
var posición = obtener_posición_final_selección()
test.innerHTML = ""
texto.split(/[\b\s\n]+/gi).map(
function(x){
var span = document.createElement("span")
var a = document.createElement("a")
span.className = "word"
span.style["background-color"] = "#abcd"
span.innerHTML = x
a.innerHTML = " \n"
test.appendChild(span)
test.appendChild(a)
}
)
try{
asignar_posición(test,posición)
}catch(e){}
});
#test{
background-color:#0123;
font-size:33px
}
<div contenteditable="true" id="test">hola mundo tierra</div>