I am trying to create a very basic rich-text editor in JavaScript but I'm having an issue with selections. So basically, since it's a contentEditable <div>, any time the user pastes in pre-formatted text from a webpage, the formatting doesn't get stripped off.
An easy to break hack is to give focus to a <textarea> upon Ctrl + V being pressed, so the text gets pasted in there, then onkeyup, give focus back to the <div>, copy the contents over and delete whatever went in to the <textarea>.
So that's easy, but when I give focus back to the contentEditable &;t;div>, the caret position is at the beginning and not immediately after the paste. I don't know enough about selections and whatnot to figure it out, so I'd appreciate some help. Here's my code:
// Helpers to keep track of the length of the thing we paste, the cursor position
// and a temporary random number so we can mark the position.
editor_stuff =
{
cursor_position: 0,
paste_length: 0,
temp_rand: 0,
}
// On key up (for the textarea).
document.getElementById("backup_editor").onkeyup = function()
{
var main_editor = document.getElementById("question_editor");
var backup_editor = document.getElementById("backup_editor");
var marker_position = main_editor.innerHTML.search(editor_stuff.temp_rand);
// Replace the "marker" with the .value of the <textarea>
main_editor.innerHTML = main_editor.innerHTML.replace(editor_stuff.temp_rand, backup_editor.value);
backup_editor.value = "";
main_editor.focus();
}
// On key down (for the contentEditable DIV).
document.getElementById("question_editor").onkeydown = function(event)
{
key = event;
// Grab control + V end handle paste so "plain text" is pasted and
// not formatted text. This is easy to break with Edit -> Paste or
// Right click -> Paste.
if
(
(key.keyCode == 86 || key.charCode == 86) && // "V".
(key.keyCode == 17 || key.charCode == 17 || key.ctrlKey) // "Ctrl"
)
{
// Create a random number marker at the place where we paste.
editor_stuff.temp_rand = Math.floor((Math.random() * 99999999));
document.getElementById("question_editor").textContent += editor_stuff.temp_rand;
document.getElementById("backup_editor").focus();
}
}
So my thinking is to store the cursor position (integer) in my helper array ( editor_stuff.cursor_position
).
NB I've been looking at other answers on SO all day and can't get any of them to work for me.
Here's a function that inserts text at the caret position:
Demo: http://jsfiddle.net/timdown/Yuft3/2/
Code:
function pasteTextAtCaret(text) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
// Preserve the selection
range = range.cloneRange();
range.setStartAfter(textNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().text = text;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.