Rich text editor is actually a very interesting topic, if you really want to go into it, there will be a lot of interesting things, but also a lot of problems. I once saw a very interesting topic on Zhihu “Why are rich text editors always said to be sinkholes? In this topic there are a lot of very reference answers, interested partners can go to see. Here I only provide a train of thought, specific also need to refer to more information to achieve ~

Preparation stage

There are several ways to implement a rich text editor on the Web. A more convenient solution that can basically meet the general needs is to utilize the contentEditable property of HTML5, combined with js document.execcommand () and some judgment methods related to execCommand. So I tried to use this scheme to write a simple rich text editor, which implements three functions: bold, set the title and set the color. The picture above gives you an idea:We must first understand the document before functionality. ExecCommand, document. QueryCommandValue, document. QueryCommandState these three methods. The specific usage will not be described here, the specific usage can be accessed through the following link:www.cnblogs.com/tugenhua070…With this knowledge in mind, we can now start implementing the functionality. The main premise is that the tags for the packages need to add the contentEditable property.

<p contenteditable="true"> </p>Copy the code

bold

With contenteditable set up, you can use Document. execCommand to implement the three functions described above. Implementing bold is easy. Use the bold command in execCommand.

document.execCommand("bold", false, null)
Copy the code

Set the title

Function of the title is not so simple, need to use the document first. QueryCommandValue do some judgment, to ensure that the function can be normal use.

if (document.queryCommandValue('formatBlock')! =="div"&&document.queryCommandValue('formatBlock')! =="") { document.execCommand("formatBlock", false, "div") } else { document.execCommand("formatBlock", false, "H1") }Copy the code

Set the color

is used to set the color

ExecCommand ("foreColor", false, e.targe. value) // e.targe. value is the color value obtained in the inputCopy the code

Some things that need to be optimized

At this point you might think the editor is complete, but there are a few areas that need to be optimized

  1. Cannot store selection (once a non-input field is clicked, the previous selection disappears and cannot be recovered)
  2. Unable to determine command status (unable to complete interaction status of function buttons)

Save selection

So how do you store a Selection, where we’re talking about Selection objects

The Selection object represents the range of text or the current position of the caret selected by the user.

The idea here is to store the most recent selection and then restore it as needed. In particular, the Range of the Select object is returned as a Range object. The implementation code is as follows:

Tip: You need to set a global variable to hold the Range

// golbal.js
let Global = {
   	range: null
}
Copy the code
Class selection {constructor() {} static saveSelection() {let range = Window.getselection ().getrangEat (0) global.range = range} static recoverSelection() {let selection = window.getSelection() selection.removeAllRanges() selection.addRange(Global.range) } }Copy the code

Then set the save selection function in the input box

Element ['onmouseup'] = function(e) {selector. SaveSelection ()}Copy the code

The problem is solved by using the self.recoverSelection () method before each use of the command, as shown here in bold

// Restore the select.recoverSelection() document.execCommand("bold", false, null)Copy the code

Judgment of command status

Another problem is how to judge the state of the command, here will be used to document. The queryCommandValue and document queryCommandState. Global variables are also used to store the status of the command.

let Global = {
	range: null,
    bold: false,
    head: false
}
Copy the code

Then is to use the document. QueryCommandValue, document. QueryCommandState to check the status of orders.

/ / bold command determine Global. Bold = document. QueryCommandState (' bold ') / / head command to judge the if (document. QueryCommandValue (' formatBlock)! =="div"&&document.queryCommandValue('formatBlock')! =="") { Global.head = true } else { Global.head = false }Copy the code

Here, the function of the editor is basically realized, the specific implementation can refer to my github, address: github.com/hahaaha/Ric…

Refer to the content

  • Why rich Text Editors are Sinkholes?
  • document.execCommand mdn
  • ExecCommand in HTML5
  • selection mdn
  • range mdn