Have you ever wondered how hard it would be to recreate a text editor like the one we use right here on Medium?
If you haven’t seen Medium’s text editor, I would highly recommend checking it out. You are able to write, edit, and style your content (within Medium’s provided styles) right here in your browser.
No tech knowledge is needed. No html tags appear in the text.
Take a look:
Hopefully that example demonstrated a few things for you:
You have two options.
document.designModefor the entire document, and
element.contentEditablefor just one element.
The browser gives us all the methods we need. Anything outside of document.execCommand is simply for demonstration purposes and error handling.
The commands modify the HTML by adding new tags around our content. This allows us to use CSS to style those tags. So simple.
The only “gotcha” is that you have to use
event.preventDefault();if you trigger the command from a button click. Otherwise the focus will shift to the button and the command will fail.
If nothing is selected, the command will fail (sometimes).
If it serves your purposes better, you can also create editable content with HTML.
<div contenteditable="true"> This text can be edited! </div>
This could work nicely with frameworks like React, Angular, etc. Where you could use a component’s state to control if the content is editable.
Using The Data
Either way you need to:
Get the new text when it changes.
Make sure the text is safe.
Render back your entire HTML.
Below you will find the same example above, but this time when you change the text there will be some information logged to the console. I am using the MutationObserver API to watch for these changes.
So what did I do?
I added an attribute to every element that I wanted to watch. You don’t have to do this, but it lets you hone in on specific editable items. If you do this, be careful not to turn on edit mode for tags you aren’t watching for changes.
I inspected the mutations to find out if they contained the attributes I was looking for. If they did, I sent that element’s attribute name and new content to the output (in this case, the console).
Hi, I’m Justin Fuller. I’m so glad you read my post! I need to let you know that everything I’ve written here is my own opinion and is not intended to represent my employer in any way. All code samples are my own and are completely unrelated to my employer's code.