高度自適應的textarea,這個需求還是比較常見的,隨着用戶的輸入textarea的高度自動變化,這樣輸入較少的時候可以節省空間,輸入多的時候可以不出現滾動條,讓內容盡可能的展現在用戶的視線內。
可惜的是textarea本身沒有自適用的技能,文字過多就會出現滾動條的,所以我們需要曲線救國。
基本思路:另外找一個元素,和textarea設置一樣的樣式,當textarea輸入的時候,將內容填充到該元素內,然后再將該元素的高度賦值給textarea。
這個元素比較苛刻了,不僅要接收textarea的文字內容,也要接收格式,比如回車什么的,很明顯是pre標簽了。
寫在pre標簽里的東西可以原格式輸出,如果要在別的元素,比如div上實現類似的效果,可能需要使用一些CSS,比如white-space:pre,諸如此類的代碼。
直接上代碼了:
首先准備一個pre,一個textarea:
<pre class="input" id="pre"></pre> <textarea class="input" id="textarea"></textarea>
然后給他們設置相同的樣式:
.input { padding: 10px; width: 300px; min-height: 150px; border: 1px solid #ccc; resize: none; font-size: 20px; line-height:30px; overflow: hidden; word-wrap: break-word; }
這里設置了min-height,給他們一個最小高度,里面的字體行高的都設置的一樣,這樣他們的表現就一致了。注意:為了純英文的換行,加上word-wrap。
最后一段簡單的腳本:
var textarea = document.getElementById('textarea'); var pre = document.getElementById('pre'); textarea.oninput = function() { pre.textContent = textarea.value; textarea.style.height = pre.offsetHeight + 'px'; }
監聽textarea的input事件,更新自身的高度。
這時候,高度自適應的textarea已經構造完成了。但是pre這個元素我們是不想讓他顯示的,需要把他隱藏掉,但不能簡單的display:none,這樣就取不到pre的高度了,所以使用另外一個屬性visibility,不過這個屬性還是會占用空間的,把pre絕對定位即可:
.hide { position: absolute; z-index: -100; visibility: hidden; } <pre class="input hide" id="pre"></pre>
大功告成!
不過還有一些兼容性工作要做,IE8以下是不支持oninput事件的,但他們支持一個更強大的屬性:onpropertychange。
可能有的童鞋會覺得可以使用onkeyup或者onkeydown事件,我在chrome下試驗了下,在textarea改變高度的時候,會有閃動,oninput的表現就比較平滑。推薦使用oninput。
完。