I'm creating a simple typing tool (I have to use IE11). Note that this does not happen in Firefox, where everything works just fine.
The execCommand forecolor is giving me a undesired result:
I type some text with black, then let's say I want to type inside one of the black words but with a different color. If I place the caret in the word and click the new color I want to use (which executes document.execCommand('foreColor', false, currentForeColor);) the whole word will become of the newly selected color. If I first select the color and then place the caret in the middle of the word, the color will remain black (this also happens on Firefox).
There are a few screenshot to give an idea.
Type some black text:
Click in the middle of the word and select a color:
The actual desired result:
What I would like to achieve is that once you chose a color it will type with that color wherever you place the caret and without affecting the present words.
The solution to this issue was to set the color each time the user types in a character.
event.preventDefault();
var tmpHtml = "<font color='" + currentForeColor + "'>" + event.key + "</font>";
pasteHtmlAtCaret(tmpHtml);
console.log(tmpHtml);
And the function I use to paste html (found here: pastHtmlAtCaret)
function pasteHtmlAtCaret(html, selectPastedContent) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
if (selectPastedContent) {
range.setStartBefore(firstNode);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if ( (sel = document.selection) && sel.type != "Control") {
// IE < 9
var originalRange = sel.createRange();
originalRange.collapse(true);
sel.createRange().pasteHTML(html);
if (selectPastedContent) {
range = sel.createRange();
range.setEndPoint("StartToStart", originalRange);
range.select();
}
}
}
Of course it's not a perfect solution, and after a certain number of elements the typing starts to get laggy.