Textarea-remind textarea to remind
Through this sharing, we know that
1. The idea of developing AT functions based on Textarea can help people to avoid some detours when developing similar scenario components in the futureCopy the code
Components based on vuE-AT customized development of completed business components, the wheel inside is divided into two cases
- At function developed based on div contentEnable attribute
- At function developed based on Textarea
Why did you choose textarea?
For example, if you want to leave div contentEnable behind, you might have more problems with it.
Some problems to be expected: copy and paste, as well as custom tags, cursor movement, etc
Ideas and problems encountered
Textarea is based on yes highlighting
It is not highlighted in the Textarea layer, but in the rendering layer underneath the Textarea
Referring to the react-mentions demo, the basic principle is that textarea is positioned to overlap exactly with the bottom rendering layer, exactly the same font size, exactly the same font style, and then the background layer with the background color
The text layer is positioned by modification, above the rendering layer
Rendering layerBy CSS propertieswhite-space: pre-wrapPositioning to complete
I made a sketch
Problems encountered:
1. Division of paragraph names
The basic idea is to partition literal names according to the specified usage rules
Initially, wrap the span note with the name of the partitioned person and output it to the render layer once through V-HTML, but the background layer of the render layer will flash frequently as the text continues to be typed
Solution:
Conversion to v-for output array rendering, so that when vUE output virtual DOM, compared to the previous input text text virtual DOM content is changed, it will not be re-rendered.
Determine if the person name in the front-end pool is present once during a single rendering, and then highlight it.
Computed: {matchingUserNameText: {get () {// renderLayerText: renderLayerText // at: current at symbol let {renderLayerText: Text, at} = this let tempContent = "let tempArray = [] for (let index = 0, len = text.length; index < len; index++) { const char = text[index] if (char === at && tempContent) { tempArray.push(tempContent) tempContent = '' } if (char === SPACE && tempContent) { tempArray.push(tempContent) tempContent = '' } tempContent += char } if (tempContent) { tempArray.push(tempContent) tempContent = '' } return tempArray }, set (val) { this.matchingUserNameText = val } } }Copy the code
2. The textarea layer directly keeps pressing enter, and the cursor is stuck only when the cursor occupies a single line of text at the bottom, which will cause dislocation with the rendering layer
As long as no single cursor occupies the bottom row, the render layer is triggered to render successfully
Solution:
A
tag is placed directly at the end of the render layer output, so that each render layer will be rendered according to the position of the < BR > tag
3. During Chinese input, there are candidate words that fail to fall into textarea, which will also cause dislocation of rendering
Solution:
Prepare two layers of text objects, one layer for user input in text objects, and one layer for rendering text objects
The home input synchronizes the rendering layer text object every time the text changes. The key is to listen for the CompositionUpdate event on the Textarea object
/ / processing input method input text not defeated candidate for input box of time synchronization of background rendering layer onCompositionupdate (textarea) {textarea. AddEventListener (' compositionupdate ', (event) => {// text layer text object const {text} = this // get the current cursor position const index = textarea.selectionStart // Split the first half of the text const startStr = String(text).substr(0, Const endStr = String(text). Substr (index) // Output to computed matchingUserNameText this.renderLayerText = `${startStr}${event.data}${endStr}` }) }Copy the code