CSS textarea高度自适应的另类实现(HTML5 contenteditable)

本文探讨了一种在移动H5场景下,如何利用HTML5的contenteditable属性替代textarea,创建一个初始单行、内容换行后自动扩展高度的输入框。通过分析输入框自动调整高度的需求,提出使用div元素加contenteditable属性的解决方案,并通过监听keyup事件动态获取内容。这种方法避免了基于textarea滚动条的复杂调整,同时提供了类似块级元素自动撑开的体验。文章还给出了示例代码并总结了contenteditable的相关参考资料。

介绍

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>标题:&nbsp;</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文件打开查看效果)

  1. 在div中增加contenteditable属性使元素可编辑
  2. css设置div的min-height,确定元素的最小高度,这样在输入文字换行时高度便会自动撑开。
  3. 设置display: inline-block; 使其成为行内元素,配合min-width和max-width便实现了宽度的自动撑开。
  4. 使用.textContent获取文字(使用innerHTML可能会得到含有<br>或其他字符的内容)

样式级行为基本靠html和css实现了,那么如果要动态获取输入的内容呢?

由于使用div元素的缘故,无法使用input/textarea 的change事件。

在这里可使用keyupinput等事件代替。即使相较change事件牺牲了部分性能,但应该可以用防抖函数解决。

 

运行结果

小结

html5虽然推出很久了,但是一些偏门的特性虽然一般开发的情况下用不到,但还是需要时不时回顾和总结。

这种方法,避开了前端开发的 “输入框一定要使用input/textarea” 的定向思维,充分利用html5的新特性,可以算是一种“另类”实现吧。

 

参考资料

  1. 可以给contenteditable添加change事件吗
  2. contenteditable元素的change事件

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值