多个textarea自动扩展失效的jQuery问题排查与解决
嘿,我来帮你搞定这个多textarea自动扩展的问题!
为啥多个textarea会失效?
核心问题出在你用的one()方法上——这个方法的特性是绑定的事件只会触发一次,不管页面上有多少匹配的元素。当第一个带autoExpand类的textarea获得焦点后,初始化baseScrollHeight的逻辑就执行完了,这个focus.autoExpand事件也会被自动解绑。后面的textarea再获得焦点时,根本不会触发初始化逻辑,缺少了计算高度必需的基准值,自然就没法正确扩展高度了。
修复方案
把one()换成on(),同时给初始化逻辑加个判断,确保每个textarea只执行一次初始化操作,避免重复操作影响体验。
修改后的JavaScript代码
$(document) .on('focus.autoExpand', 'textarea.autoExpand', function(){ // 只有当元素还没初始化基准高度时,才执行初始化 if (!this.baseScrollHeight) { var savedValue = this.value; this.value = ''; this.baseScrollHeight = this.scrollHeight; this.value = savedValue; } }) .on('input.autoExpand', 'textarea.autoExpand', function(){ // 用parseInt替代|0,可读性更好 var minRows = parseInt(this.getAttribute('data-min-rows')) || 0, rows; this.rows = minRows; rows = Math.ceil((this.scrollHeight - this.baseScrollHeight) / 16); this.rows = minRows + rows; });
这里做了两个关键调整:
- 把
one()改成on(),让每个textarea获得焦点时都能触发初始化逻辑 - 增加
if (!this.baseScrollHeight)判断,确保每个文本框只初始化一次,避免重复清空/恢复内容的冗余操作
完整可运行代码
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <style> /* JUST FOR THIS DEMO */ html, body { height: 100%; } body { background: #4A90E2; display: flex; flex-direction: column; align-items: center; padding-top: 20px; } textarea { display: block; box-sizing: padding-box; overflow: hidden; padding: 10px; width: 250px; font-size: 14px; margin: 10px auto; border-radius: 6px; box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3); border: 0; } </style> <textarea class='autoExpand' rows='3' data-min-rows='3' placeholder='Auto-Expanding Textarea'></textarea> <textarea class='autoExpand' rows='3' data-min-rows='3' placeholder='Auto-Expanding Textarea'></textarea>
(顺便微调了CSS的布局,让两个textarea显示更紧凑合理,不影响核心功能)
额外说明
- 每个textarea的
baseScrollHeight会存在自身的DOM属性上,各个元素之间互不干扰,保证独立计算高度 input事件会覆盖用户输入、粘贴、删除等所有需要调整高度的场景- 保留了
data-min-rows属性,你可以给不同的textarea设置不同的最小行数
内容的提问来源于stack exchange,提问作者Vlada
相关产品推荐
相关产品推荐

