Aaron Christiansen
Aaron Christiansen

Reputation: 11807

Allow moving out of a span at the end of a contenteditable

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:

  1. Run the Stack Snippet above
  2. Select the text from somewhere in the middle til the end, then click Create Span
  3. Type some new text at the end of the line

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.

https://i.imgur.com/QEcDhHi.gifv

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

Answers (1)

Tarun Lalwani
Tarun Lalwani

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/

Edit content outside

Upvotes: 7

Related Questions