[转载]自适应高度输入框

初步实现代码以下: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 来源:掘金 著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
相关文章
相关标签/搜索