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
- Cannot store selection (once a non-input field is clicked, the previous selection disappears and cannot be recovered)
- 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