介绍
textarea相较于input输入框多了换行的功能。
但是有些场景设计下(尤其是移动H5的需求),希望输入框高度开始只有一行高,输入文字换行后,高度自动撑开。这个时候使用textarea就显得不那么好用了
经过一段时间百度,许多资料都说使用js来获取textarea的滚动条的高度信息,动态计算和调整textarea的高度。
问题
这种方法的问题是,它是基于类似监听滚动条是否出现来控制textarea高度变化。在输入文字的时候,换行若文字超过高度,则滚动条出现,然后触发js调整高度。
然而如果是删除文本的情况下,滚动条永远不会出现,这个办法就调整不了textarea的高度。就得依靠其他办法来实现。
那么此时是否可以通过尽量简单的方法来实现呢?
分析
对于自动调整textarea高度的行为来看,其实很像html 块级元素自动撑开父元素的行为。
那么如果让输入的文字写入块级元素中,那么自动扩充高度不就实现了吗。
所幸,html5为元素提供了contenteditable 属性,使元素拥有编辑的能力。
实现
<!DOCTYPE html>
<html lang="zh_CN">
<style>
.my-textarea {
display:inline-block; /*使宽度也能自动撑开*/
min-width: 100px;
max-width: 200px;
min-height: 20px;
outline: none;/*取消成为焦点时的边框*/
padding: 5px 10px;
border: 1px #ddd solid;
border-radius: 5px;
transition: all .2s ease;
}
.my-textarea:focus{
box-shadow: 0 0 10px #aaa;
}
</style>
<body>
<span>标题: </span>
<div id='textarea' class="my-textarea" contenteditable></div>
</body>
<script>
let textarea = document.querySelector('#textarea');
textarea.addEventListener('keyup',(e) => {
console.log(textarea.textContent);
})
</script>
</html>
如上代码(代码可以直接复制保存到.html文件打开查看效果)
- 在div中增加contenteditable属性使元素可编辑
- css设置div的min-height,确定元素的最小高度,这样在输入文字换行时高度便会自动撑开。
- 设置display: inline-block; 使其成为行内元素,配合min-width和max-width便实现了宽度的自动撑开。
- 使用.textContent获取文字(使用innerHTML可能会得到含有<br>或其他字符的内容)
样式级行为基本靠html和css实现了,那么如果要动态获取输入的内容呢?
由于使用div元素的缘故,无法使用input/textarea 的change事件。
在这里可使用keyup或input等事件代替。即使相较change事件牺牲了部分性能,但应该可以用防抖函数解决。
运行结果


小结
html5虽然推出很久了,但是一些偏门的特性虽然一般开发的情况下用不到,但还是需要时不时回顾和总结。
这种方法,避开了前端开发的 “输入框一定要使用input/textarea” 的定向思维,充分利用html5的新特性,可以算是一种“另类”实现吧。
参考资料
本文探讨了一种在移动H5场景下,如何利用HTML5的contenteditable属性替代textarea,创建一个初始单行、内容换行后自动扩展高度的输入框。通过分析输入框自动调整高度的需求,提出使用div元素加contenteditable属性的解决方案,并通过监听keyup事件动态获取内容。这种方法避免了基于textarea滚动条的复杂调整,同时提供了类似块级元素自动撑开的体验。文章还给出了示例代码并总结了contenteditable的相关参考资料。
&spm=1001.2101.3001.5002&articleId=114439513&d=1&t=3&u=f1677b67be9c40c69b6f3af1d7fee2dc)
3427

被折叠的 条评论
为什么被折叠?



