文本框是一种很常见的输入控件。相信写过form的人一定都接触过textarea元素。好的。但是现在产品经理说:这个文本框需要能够根据用户输入的内容自适应高度。height:auto初学者可能会想:自适应高度不就是height:auto吗?但是你想一想,如果一个textarea没有手动指定样式,那不应该默认是height:auto吗?但是它仍然有自己的初始高度,而不是像div那样的0高度。与div不同,textarea的默认高度不是根据其内容自适应的,而是由rows属性指定的,默认值为2。rows属性(Attribute)只接受正整数,如果指定其他值,则浏览器将忽略它的值。比如你写rows="auto",那么rows就是2,rows="0"也是2。所以指定height:auto是行不通的,height属性必须手动指定它的值。scrollHeight遇到过这个问题的同学(比如原作者)一定想到了scrollHeight这个DOM属性。这个想法很简单。当用户输入的文字超过文本框本身的高度时,就会出现滚动条,那么很自然的就会想到scrollHeight这个属性。scrollHeight应该是用户输入的文本的真实高度,至少如果它超过了文本框的给定高度。那么问题来了:不超过怎么办?好的,我知道您将首先指定rows="1"以使文本框默认为一行高度。但考虑这种情况:用户首先输入多行文本,然后删除一个部分:scrollHeight值没有改变。MDN说:在没有垂直滚动条的情况下,scrollHeight值与元素视图填充所有内容所需的最小clientHeight相同。scrollHeight确实会随着用户输入内容而增加或减少,但只有在出现滚动条时才会增加或减少。这种情况肯定不适用于问题设置,因为要求是不出现滚动条(严格来说是超出可见区域)。在获取scrollHeight值之前,可以通过将textbox的高度设置为0来强制出现滚动条,但是这样可能会导致页面闪烁,性能不佳。split('\n')DOM属性不靠谱,我可以自己计算文字高度吗?假设我取出所有文本,按换行符拆分,然后查看有多少行。行数*行高不就是最终的文字高度吗?前额。..这是文本未换行时的情况。..contenteditablecontenteditable确实是一个(相对)可行的方案,但是作为踩过坑的先行者,奉劝各位:不到万不得已不要碰contenteditable。这个东西在不同的浏览器中的实现是不一样的,各种奇怪的行为,光是换行就够折磨你半天了。当然,现在还没有那么复杂,但是你得先能把过去“复制粘贴”的样式去掉。作者的方法说了那么多废话,那怎么办呢?这里作者提供了一种方法。当然,首先声明:作者的方法可能不是最简单的。如果大家有其他更简单的解决方案,欢迎留言建议。大家想一想,textarea不能根据内容调整高度,div可以,可不可以先把文字填充到div中,div的高度应该是文本框需要的高度(padding时,line-height等样式一致大小写),然后获取div的高度赋给文本框的高度。这就是思维方式。我们不需要用JS来获取,只需要让div撑起父元素,绝对定位textarea元素,让文本框占满父元素的整个大小。直接添加代码:
