Context:
I'm working on an in-browser WYSIWYG editor in vanilla javascript, and it's mostly for personal use. However, the document.execCommand standard is obsolete, and I'd like to work on adding bold and italics into my editor.
My editor is a contenteditable <div> element, and it separates lines into child <div>s. When the Enter key is pressed, it automatically creates a new div that is being worked in. That's just the nature of contenteditable.
The Problem:
I can't seem to figure out how to move the cursor caret past the element it's in. What I want to do is get the element, close it, and move to a new one. The way I would guess to do this is append </div><div> to the current element's innerHTML and move the cursor past it with Selection.Modify, but that doesn't seem to work.
If it were the end of the file, I would simply add the tags and move the cursor to the end, but I need it to work within context.
My Code:
<div id="editor">
<div>foo</div>
<br>
<div>bar</div>
<br>
<div>foobar</div>
<!-- cursor^ ^where it should be
-->
</div>
//get working element if that helps
let element = window.getSelection().anchorNode.parentElement; //useful tool for debugging
//insert text works fine, but can't figure out how to insert element tags into innerHTML
function insertText(text){
let selection = window.getSelection(); //get selection
let range = selection.getRangeAt(0); //get range
range.deleteContents(); //clear gunk
let node = document.createTextNode(text); //create a node to append. Problem starts here.
range.insertNode(node); //insert the node at the cursor
for(let char of text)
selection.modify('move','left','character'); //move cursor past inserted text
}
If you can help at all, I'd greatly appreciate it.
It had a different issue. The thing I'm working on adds wrappers to words when specific words are found. The problem was, that if I clicked at the end of the marked word, the caret was inside the wrapped element and if I continued typing the new words kept the wrapper style.
So, this is not what you want exactly, but I hope it helps.
Best of luck.
function clickOutside(){
var nodes = textarea.querySelectorAll("mark");
for (let n of nodes){
n.addEventListener("click", function (event){
if(!n.classList.contains("clicked")){
co(n);
n.classList.add("clicked");
} else if (n.classList.contains("clicked")){
n.classList.remove("clicked");
}
})
}
}
//relavent part
function co(node){
var el = node
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el.nextSibling, 0);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
el.focus();
}