To complete the task specified in the summary, try changing the node value at the current cursor position. Since your code is attached to the keyup event, you can be sure that the range is already minimized by the node text (all this happens when you press a key that has already been started).
function insertChar(char) { var range = window.getSelection().getRangeAt(0); if (range.startContainer.nodeType === Node.TEXT_NODE) { range.startContainer.insertData(range.startOffset, char); } } function handleKeyUp(e) { e = e || window.event; var char, keyCode; keyCode = e.keyCode; char = (e.shiftKey ? { "222": '"', "57": ')', "219": '}' } : { "219": "]" })[keyCode] || null; if (char) { insertChar(char); } } document.getElementById("editable").onkeyup = handleKeyUp;
Fiddle
In addition, I see that you used innerHTML to set a new value (in Element.prototype.setText ). That sounds alarming! innerHTML completely destroys all contents previously in the container. Since the cursor is bound to a specific element, and these elements have just received a nuk, what should the browser do? Try to avoid using this if you don't care about where your cursor ends at all.
Regarding the highlightText problem, it's hard to say why it is broken. Your violin does not show that it is used anywhere, and I will need to see its use for further diagnosis. However, I have an idea of ββwhat might go wrong:
I think you should look carefully at getCaretPosition . You treat it as if it were returning the cursor position, but thatβs not what it does. Remember that in the browser, your cursor position is always a range. It always has a beginning and an end. Sometimes, when a range falls, the beginning and end are the same. However, the idea that you can get the cursor position and view it as one point is a dangerous simplification.
getCaretPosition has another problem. For your editable div it does this:
- Selects all text in a new range.
- Resets the end position of the new range to the equal end position of the cursor (so that all text to the end position of the cursor is selected).
- Calls
toString() and returns the length of the resulting string.
As you noticed, some elements (e.g. <br /> ) affect the results of toString() . Some elements (e.g. <span></span> ) do not work. To correctly perform this calculation, you need to push it for some types of elements, and not for others. It will be dirty and difficult. If you need a number that you can pass into highlightText , and let it work properly, your current getCaretPosition unlikely to be useful.
Instead, I think you should try working directly with the start and end points of the cursor as two separate locations and update highlightText accordingly. Cancel the current getCaretPosition and use your own browser concepts range.startContainer , range.startOffset , range.endContainer and range.endOffset .