Reputation: 11807
I'm trying to write a basic text editor using contenteditable
. In this MCVE, it only has one function, which is that selected text is given a red highlight.†
The code I'm using is here:
function createSpan() {
let selection = document.getSelection();
let range = selection.getRangeAt(0);
let element = document.createElement("span");
element.className = "inline-equation";
range.surroundContents(element);
let newRange = new Range();
newRange.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(newRange);
}
$("button").click(createSpan)
.inline-equation {
background-color: red;
display: inline-block;
}
#editor {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>
Create Span
</button>
<div id="editor" contenteditable="true">
This is a contenteditable area.
</div>
I'm having trouble with the idea that the user may move out of the highlight area and continue typing in unformatted text. To experience this issue:
This new text has the red highlight too, even if you attempt to move out of the inserted span
by pressing the right arrow key.
I'd still like to give the user the option to append new text which is formatted, but then also allow the user to navigate out of the span
so that they may continue to type normal text.
In other words, the span
should act as a completely separate editable object which may be moved into or out of. This includes the ability to move out of the span
even if it's at the end of the document, so that the user can continue typing in non-formatted text.
The best example I am able to give of what I'd like is Microsoft Word's inline equations. Notice how, in the GIF below, the equation acts as a separate object, which I may navigate out of so that I can type normal text to the right of it. The is how I'd like my span
to act.
I've tried replacing the span
with a div
with inline-block
formatting to see if that affected the behaviour, but it didn't. How should I achieve the effect I'm looking for?
† In the actual use case, the 'highlight' actually denotes LaTeX-formatted mathematics which are rendered later. I'm writing what is essentially an editor for a proprietary markup language which supports inline LaTeX.
Upvotes: 3
Views: 1391
Reputation: 146510
The issue is that you need something editable at end for this to work. There are lot of existing SO thread for the same. You can see below
Why Is My Contenteditable Cursor Jumping to the End in Chrome?
contenteditable put caret outside inserted span
contenteditable with nested span. Who has the focus?
Focusing on nested contenteditable element
Combining knowledge from above thread the simplest thing I could think of was adding below keyup
handler
$("#editor").on('keyup',(e) => {
var editor = $("#editor").get(0)
var cn = editor.childNodes;
if (cn[cn.length - 1].nodeType !== Node.TEXT_NODE)
{
empty = document.createTextNode( '\uFEFF' );
editor.appendChild(empty);
}
if (cn[0].nodeType !== Node.TEXT_NODE)
{
empty = document.createTextNode( '\uFEFF' );
editor.prepend(empty);
}
})
Which makes sure there is one text node to step out of the div. You can do the same thing for the starting div
if you want. Below is JSFiddle for the same
https://jsfiddle.net/4tcLr0qa/1/
Upvotes: 7