[转载]自适应高度输入框
初步实现代码如下:
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';
});
复制代码
然而,当内容高度缩减时,输入框的高度并没有跟随缩减。
由于根据scrollHeight设置的元素高度的存在,即使内容高度缩减,此时scrollHeight也不会低于元素高度。所以,在做自适应高度缩减时就无法直接通过同步scrollHeight来实现,而是要先清掉高度样式:
$textarea.addEventListener('input', function() {
// 清除原来高度
$textarea.style.height = '';
$textarea.style.height = $textarea.scrollHeight + 2 + 'px';
});
复制代码
实现后发现,输入到临近换行处,内容高度提前增高了。
调试后发现,清掉高度样式后,textarea恢复到原来的高度,此时内容超过textarea高度,因此会出现滚动条。滚动条会占据一定的空间,导致一行能容纳的字符减少,于是就提前换行了(如下图所示)。而因为在清理高度样式后,又立刻把高度设为新的scrollHeight,所以在界面上没有体现出现。
要解决这个问题,只需要把滚动条隐藏掉。
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;
});
自己写的一个,有点bug,聚焦的时候输入框没清空 <div class="list-group-textarea" id="groupAreaEle" :value="desc" placeholder="填写聚会介绍,详细介绍主题、费用、流程等" v-on:input="onInputDesc | debounce 500" contenteditable="true"></div> <div class="list-blank"></div> <span class="counter" v-html="teatareaWordCount"></span> .list-group-textarea { width:100%; min-height:shift(138); font-size:shift(26); font-weight:400; color:rgba(50,51,51,1); line-height:shift(37); padding-top:shift(27); background:rgba(249,249,249,1); outline: 0 none; overflow:hidden; box-sizing:border-box; -webkit-user-select:text; -webkit-user-select:auto; &:empty:before { content: attr(placeholder); letter-spacing: 0; text-align: justify; font-size:shift(26); font-weight:400; color:rgba(205,205,205,1); } &:focus { content: none; } } .list-blank{ width:100%; height:shift(102); margin:0; padding:0; } .counter { position: absolute; right: 0; font-size: shift(24); line-height: shift(33); color: #aaaaaa; font-weight:400; }
分类:
前端
, HTML5/CSS3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述