先來幾張簡單圖:
基本思路:
要想實現文本域跟隨內容自動高度,這里准備兩個textarea文本域,
文本域1:固定高度,超出部分滾動,設置絕對定位放到文本域2下面不做顯示,但是注意不要設置為隱藏,否怎會讀取不到寬高
文本域2:通過css設置初始寬高與文本域1一樣,相對定位覆蓋在文本域1上,使用vue的屬性綁定 :style="{height: inputH + 'px'}" 動態的改變其高度,建議最低高度不低於文本域1的高度。
通過 v-model="source.txt" 將文本域2中輸入的內容寫入文本域1中,因文本域1固定高度超出滾動,然后通過vue的 watch 監聽數據 source.txt 的變化,在監聽中讀取文本域1的滾動高度$refs.transInput0.scrollHeight 並設置文本域2的高度 this.inputH = this.$refs.transInput0.scrollHeight,為防止輸入過程中出現頻繁的高度變化造成閃爍設置延時 setTimeout(() => {}, 1000) 和 (tims - this.times < 1000),即停止輸入1000ms后或兩次輸入間隔超過1000ms時才會進行高度的設置變化。
具體代碼:
<template> <div class="part-top"> <div class="trans-wrap layui-row"> <div class="layui-col-md6 trans-left"> <div class="input-wrap"> <textarea ref="transInput0" v-model="source.txt" :class="['layui-textarea', 'txt0', {'more': source.txt.length > 23}]" /> <textarea ref="transInput" v-model="source.txt" :class="['layui-textarea', 'txt', {'more': source.txt.length > 23}]" :style="{height: inputH + 'px'}" @keydown="interpretListen" /> <span v-show="source.txt" class="layui-icon layui-icon-close" @click="clear()" /> </div> </div> <div class="layui-col-md6 trans-right"> <div ref="transOutput0" :class="['output-wrap', 'out0', {'more': target.txt.length > 25}]"> <p>{{ target.txt }}</p> </div> <div ref="transOutput" :class="['output-wrap', {'more': target.txt.length > 25}]" :style="{height: outputH + 'px'}"> <p>{{ target.txt }}</p> </div> </div> </div> </div> </template> <script> export default { name: 'IdentifyPane', props: { name: { type: String, default: '' }, moduleId: { type: String, default: '' }, iUri: { type: String, default: '' }, index: { type: Number, default: -1 }, enabled: { type: String, default: 'false' } }, data() { return { // 初始化標識 完成后即為false isInit: true, // 是否顯示當前模塊 isShow: false, datas: {}, inputH: 130, outputH: 155, source: { flag: 'source', txt: '' }, target: { flag: 'target', txt: '' }, langsBox: { show: false, for: '' }, times: 0, timeout: undefined } }, watch: { // 動態監聽數據是否變化 'source.txt': function(newVal, oldVal) { // console.log(`new value -> ${newVal}\nold value -> ${oldVal}`) this.resetTransHeight() }, 'target.txt': function(newVal, oldVal) { // console.log(`new value -> ${newVal}\nold value -> ${oldVal}`) this.resetTransHeight() }, isShow: function(newVal, oldval) { if (newVal) { setTimeout(() => { // console.log(`${this.$refs.transInput.offsetWidth} ->>>- ${this.$refs.transOutput.offsetWidth}`) this.$refs.transInput0.style.width = this.$refs.transInput.offsetWidth + 'px' this.$refs.transOutput0.style.width = this.$refs.transOutput.offsetWidth + 'px' }, 100) } } }, created() { this.source.lang = this.languages[1] this.target.lang = this.languages[0] // console.log(this.source) // console.log(this.target) this.datas[this.moduleId] = [] }, mounted() { }, methods: { showModule() { this.isShow = true }, // 點擊面板標題 顯示(展開)/隱藏(收起)面板 showHidePanel(index) { this.datas[this.moduleId][index]['isShow'] = !this.datas[this.moduleId][index]['isShow'] this.$forceUpdate() }, resetTransHeight() { const tims = new Date().getTime() if (!this.timeout) { this.timeoutReset() } if (this.times === 0) { this.times = tims } else { if (tims - this.times < 1000) { clearTimeout(this.timeout) this.timeoutReset() this.times = tims } } }, timeoutReset() { this.timeout = setTimeout(() => { this.timeout = undefined const ish = this.$refs.transInput0.scrollHeight const osh = this.$refs.transOutput0.scrollHeight console.log(`input height -> ${ish}\noutput height -> ${osh}`) if (ish > osh) { this.inputH = ish this.outputH = ish + 25 } else { this.inputH = osh - 25 this.outputH = osh } this.times = 0 }, 1000) }, // 發送消息 interpret() { console.log(`interpret ->>> `) }, // 清空輸入和翻譯結果 clear() { this.source.txt = '' this.target.txt = '' }, // 文本輸入默認回車換行改為發送消息 interpretListen(event) { console.log(`key down interpret listen ->>>`) if (event.keyCode === 13) { this.interpret() // 調用發送消息 event.preventDefault() // 阻止瀏覽器默認的換行操作 return false } } } } </script> <style scoped> .trans-wrap { width: 100%; margin: 6px 0; } .trans-wrap .input-wrap, .trans-wrap .output-wrap { width: 100%; padding: 10px; } .trans-wrap .input-wrap { border: 1px solid #dcdcdc; } .trans-wrap .input-wrap>textarea { resize: none; height: 130px; min-height: 100%; font-size: 22px; display: inline-block; width: calc(100% - 20px); } .trans-wrap .input-wrap>.layui-icon-close { top: 15px; right: 5px; width: 30px; display: inline-block; } .trans-wrap .output-wrap { background: #f0f0f0; font-size: 22px; height: 155px; } .trans-wrap .output-wrap.more, .trans-wrap .input-wrap>textarea.more { font-size: 16px; line-height: 20px; } .trans-wrap .output-wrap::-webkit-scrollbar, .trans-wrap .input-wrap>textarea::-webkit-scrollbar { /* 滾動條整體樣式 */ display: none; } .trans-wrap .output-wrap.out0, .trans-wrap .input-wrap>textarea.txt0 { position: absolute; min-height: unset; z-index: -1; } /* 旋轉180° */ .rotate180 { transform: rotate(180deg); -ms-transform: rotate(180deg); /* IE 9 */ -moz-transform: rotate(180deg); /* Firefox */ -webkit-transform: rotate(180deg); /* Safari 和 Chrome */ -o-transform: rotate(180deg); /* Opera */ } </style>
每天進步一點點,點滴記錄,積少成多。
以此做個記錄,
如有不足之處還望多多留言指教!