Give the solution first. Students who need Vue stack can directly download vue-awesome-textarea Hidden ProblemsApart from native JS, most of the UI libraries of the framework support the adaptive textarea height function, but one function is generally overlooked, which is the adaptive height echo. When using these libraries, we can easily type content in the textarea, and it will automatically extend one line when it exceeds the range to ensure the content is highly adaptive. When we submit content and use the same UI to render on other pages, trouble arises. Some UI libraries do not support adaptive echo, which requires us to calculate a base value between line height, number of lines, and even height to achieve echo. Solution to adaptive height There are two common solutions. One is to add a ghost DOM in the "remote area" of the page to simulate input line breaks. This DOM may be a div with the editable attribute set to true or an identical textarea. resizeTextarea() { if (this.$isServer) return; const { autosize, type } = this; if (type !== 'textarea') return; if (!autosize) { this.textareaCalcStyle = { minHeight: calcTextareaHeight(this.$refs.textarea).minHeight }; return; } const minRows = autosize.minRows; const maxRows = autosize.maxRows; this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows); } When autosize is set to true, the textarea is set to adaptive height. At this time, the height of the textarea will be calculated in real time through the calcTextareaHeight method. export default function calcTextareaHeight( targetElement, minRows = 1, maxRows = null ) { if (!hiddenTextarea) { hiddenTextarea = document.createElement('textarea'); document.body.appendChild(hiddenTextarea); } let { paddingSize, borderSize, boxSizing, contextStyle } = calculateNodeStyling(targetElement); hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`); hiddenTextarea.value = targetElement.value || targetElement.placeholder || ''; let height = hiddenTextarea.scrollHeight; const result = {}; if (boxSizing === 'border-box') { height = height + borderSize; } else if (boxSizing === 'content-box') { height = height - paddingSize; } hiddenTextarea.value = ''; let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize; if (minRows !== null) { let minHeight = singleRowHeight * minRows; if (boxSizing === 'border-box') { minHeight = minHeight + paddingSize + borderSize; } height = Math.max(minHeight, height); result.minHeight = `${minHeight}px`; } if (maxRows !== null) { let maxHeight = singleRowHeight * maxRows; if (boxSizing === 'border-box') { maxHeight = maxHeight + paddingSize + borderSize; } height = Math.min(maxHeight, height); } result.height = `${ height }px`; hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); hiddenTextarea = null; return result; }; We can see if (!hiddenTextarea) { hiddenTextarea = document.createElement('textarea'); document.body.appendChild(hiddenTextarea); } Element-ui creates a textarea DOM and copies the style of the real textarea to the hiddenTextarea through the calculateNodeStyling method (the overflow is not synchronized, the real textarea is hidden). Then monitor the input value of textarea and synchronize it to hiddenTextarea. At the same time, synchronize the scrollHeight of hiddenTextarea to the height of textarea, and finally destroy the dom. Regarding style synchronization, element uses the two APIs getComputedStyle and getPropertyValue. Of course, if you wrap it yourself, you can also use the CSS preprocessor mixin. The second solution is similar to the first solution, but no additional DOM is created. Take the vue-awesome-textarea at the beginning as an example: init() { this.initAutoResize() }, initAutoResize () { this.autoResize && this.$nextTick(this.calcResize) } When the page is mounted or the content changes and autoResize is turned on, the this.calcResize method is executed. calcResize() { this.resetHeight() this.calcTextareaH() }, resetHeight() { this.height = 'auto' }, calcTextareaH() { let contentHeight = this.calcContentHeight() this.height = this.calcHeightChange(contentHeight) + 'px' if (this.needUpdateRows(contentHeight)) { this.updateRows(contentHeight) } this.oldContentHeight = contentHeight }, calcContentHeight () { const { paddingSize } = this.calcNodeStyle(this.$el) return this.$el.scrollHeight - paddingSize }, resetHeight() is used to initialize the height of the textarea, the default is auto. The calcTextareaH() method is used to calculate the height of the content area (the scrollHeight of the textarea minus the height of the padding), and synchronize the calculated height to the height of the textarea in real time: Compared with Solution 1, this solution adopts the same idea (dynamically modifying the height), but reduces the additional DOM creation and destruction process. computed: { ... oneRowsHeight() { return this.calcContentHeight() / Number(this.rows) || 0 } ... } In computed we calculate the height of a single line, and when executing the this.calcTextareaH() method we record the content height: this.oldContentHeight = contentHeight Next, we will check whether there is an added row operation. If it is added, the new content height will be different from the old content height: needUpdateRows(newContentHeight) { return this.oldContentHeight !== newContentHeight }, At this point we will emit the latest row height outside the component: updateRows(contentHeight) { this.$emit('getRows', Math.round(contentHeight / this.oneRowsHeight)) } This is the end of this article about the implementation of textarea adaptive height solution in Vue. For more relevant Vue textarea adaptive content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Text pop-up effects implemented with CSS3
>>: Detailed explanation of some settings for Table adaptation and overflow
Insert image tag <IMG> The colorful web page...
Table of contents The server runs jupyter noteboo...
Table of contents Preface 1. MySQL main storage e...
Find the installation directory of VirtualBox. Th...
Today, let’s get straight to the point and talk a...
<br />In previous tutorials of 123WORDPRESS....
The domestic market still has a certain demand fo...
Table of contents background CommonsChunkPlugin s...
Table of contents 1. innodb_buffer_pool_size 2. i...
This article shares the specific code of jQuery t...
Table of contents 1. Project Requirements Second,...
Table of contents Understanding SQL Understanding...
<br /> Focusing on the three aspects of text...
This article introduces in detail some of the tech...
1. Error details Once when manually performing a ...