[轉載]自適應高度輸入框

初步實現代碼以下:javascript

textarea { width: 100%; height: 92px; padding: 20px; line-height: 50px; resize: none; outline: none; border: 1px solid #ccc; background: #eee; font-size: 32px; box-sizing: border-box; } 複製代碼
<textarea id="textarea"></textarea> 複製代碼
var $textarea = document.getElementById('textarea'); $textarea.addEventListener('input', function() { // 總高度 = scrollHeight + 上下邊框的寬度(1px * 2) $textarea.style.height = $textarea.scrollHeight + 2 + 'px'; }); 複製代碼

然而,當內容高度縮減時,輸入框的高度並無跟隨縮減。css

 

輸入框的高度有誤

 

因爲根據scrollHeight設置的元素高度的存在,即便內容高度縮減,此時scrollHeight也不會低於元素高度。因此,在作自適應高度縮減時就沒法直接經過同步scrollHeight來實現,而是要先清掉高度樣式:html

$textarea.addEventListener('input', function() { // 清除原來高度 $textarea.style.height = ''; $textarea.style.height = $textarea.scrollHeight + 2 + 'px'; }); 複製代碼

實現後發現,輸入到臨近換行處,內容高度提早增高了。java

 

臨界點異常

 

調試後發現,清掉高度樣式後,textarea恢復到原來的高度,此時內容超過textarea高度,所以會出現滾動條。滾動條會佔據必定的空間,致使一行能容納的字符減小,因而就提早換行了(以下圖所示)。而由於在清理高度樣式後,又馬上把高度設爲新的scrollHeight,因此在界面上沒有體現出現。web

 

緣由

 

要解決這個問題,只須要把滾動條隱藏掉。post

textarea { overflow: hidden; } 複製代碼

雖然功能是作出來了,可是性能上還有優化的餘地。由於當前的作法,至關於每次輸入都要同步高度。若是高度沒有發生變化,這個同步操做是沒有意義的。因此,優化的思路就在於如何檢查內容高度是否發生了變化:性能

  • 內容增長時,scrollHeight有可能會發生變化,因此能夠記錄上一次的scrollHeight,並與當前的scrollHeight對比,有變化時才設置高度樣式。
  • 內容減小時,沒有有效的方式能夠知道內容高度是否有變動(scrollHeight不會減小),因此這種狀況目前沒法優化。

實現代碼以下:優化

var $textarea = document.getElementById('textarea'); var lastLength = 0; var lastHeight = 0; $textarea.addEventListener('input', function() { var currentLength = $textarea.value.length; // 判斷字數若是比以前少了,說明內容正在減小,須要清除高度樣式,從新獲取 if (currentLength < lastLength) { $textarea.style.height = ''; } var currentHeight = $textarea.scrollHeight; // 若是內容高度發生了變化,再去設置高度值 if (lastHeight !== currentHeight || !$textarea.style.height) { $textarea.style.height = currentHeight + 2 + 'px'; } lastLength = currentLength; lastHeight = currentHeight; });
做者:貝聊科技 連接:https://juejin.im/post/5b7653bde51d454dba70c0b1 來源:掘金 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索