您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Vue中textarea自適應(yīng)高度方案怎么實(shí)現(xiàn)”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
拋開原生JS,框架的大部分UI庫都支持自適應(yīng)textarea高度功能,但普遍都忽略了一個(gè)功能,就是自適應(yīng)高度的回顯。
使用這些庫的時(shí)候,我們很容易的在textarea中鍵入內(nèi)容,超出范圍時(shí)會自動延展一行,保證內(nèi)容高度的自適應(yīng)。當(dāng)我們提交內(nèi)容,在其它頁面使用同樣的UI來渲染時(shí),麻煩的就來了,有些UI庫是不支持自適應(yīng)回顯的,這就需要我們通過行高、行數(shù)甚至高度之間的計(jì)算得出一個(gè)基值,從而實(shí)現(xiàn)回顯。
常見得方案有兩種,一種是在頁面地“邊遠(yuǎn)地區(qū)”添加一個(gè)ghost dom來模擬輸入換行,這個(gè)dom的可能是editable屬性為true的div或者是一個(gè)一摸一樣得textarea。
以element-ui的input組件舉例,當(dāng)我們在組件內(nèi)輸入值時(shí),會調(diào)用resizeTextarea方法
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); }
當(dāng)設(shè)置了autosize為true則textarea設(shè)為自適應(yīng)高度。此時(shí)textarea的高度會通過calcTextareaHeight方法實(shí)時(shí)計(jì)算。
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; };
我們可以看到
if (!hiddenTextarea) { hiddenTextarea = document.createElement('textarea'); document.body.appendChild(hiddenTextarea); }
element-ui創(chuàng)建了一個(gè)textarea的dom,通過calculateNodeStyling方法將真正的textarea的樣式復(fù)制給hiddenTextarea(overflow不同步,真正的textarea是為hidden)。接著監(jiān)聽textarea的輸入值,同步給hiddenTextarea。同時(shí)將hiddenTextarea的scrollHeight同步給textarea的高度,最后再將dom銷毀掉。
關(guān)于樣式的同步,element這里用了getComputedStyle和getPropertyValue這兩個(gè)API。當(dāng)然,如果你自己封裝的話,也可以使用css預(yù)處理器的mixin。
第二種方案與第一種方案類似,不過不會創(chuàng)建額外的dom。以開頭的vue-awesome-textarea舉例:
init() { this.initAutoResize() }, initAutoResize () { this.autoResize && this.$nextTick(this.calcResize) }
在頁面mounted或者內(nèi)容變動且開啟自適應(yīng)高度autoResize的時(shí)候,執(zhí)行this.calcResize方法。
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()是來初始化textarea的高度,默認(rèn)為auto。calcTextareaH()方法是用來計(jì)算內(nèi)容區(qū)域的高度(textarea的scrollHeight減去padding的高度),同時(shí)將計(jì)算好的高度實(shí)時(shí)同步給textarea的高:
this.height = this.calcHeightChange(contentHeight) + 'px'
相比方案一,這個(gè)方案采用的思路相同(動態(tài)修改高度),但是減少了額外的dom創(chuàng)建和銷毀的過程。
此外,vue-awesome-textarea還支持在自適應(yīng)的過程中回調(diào)行數(shù),可以更好的支持?jǐn)?shù)據(jù)回顯。實(shí)現(xiàn)的方法也很簡單:
computed: { ... oneRowsHeight() { return this.calcContentHeight() / Number(this.rows) || 0 } ... }
在computed中我們計(jì)算出單行的高度,同時(shí)在執(zhí)行this.calcTextareaH()方法時(shí)我們記錄下內(nèi)容高度:
this.oldContentHeight = contentHeight
接著我們會比對是否存在添加行操作,一旦添加則新的內(nèi)容高度和老的內(nèi)容高度會不同:
needUpdateRows(newContentHeight) { return this.oldContentHeight !== newContentHeight },
此時(shí)我們會把最新的行高emit到組件外部:
updateRows(contentHeight) { this.$emit('getRows', Math.round(contentHeight / this.oneRowsHeight)) }
“Vue中textarea自適應(yīng)高度方案怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。