Rails框架下如何实现text_area根据换行符动态调整高度
实现方案
首先明确:Rails的ERB模板是服务端渲染逻辑,仅在页面首次加载、服务端响应重渲染时执行,渲染完成后生成的是静态HTML,没有React这类前端框架的客户端状态自动重渲染能力,用户输入触发的动态调整必须通过前端JavaScript实现。
你之前代码失效的核心原因是:rows: (@direct_message.body || "\n").lines.count是服务端渲染时计算的固定值,渲染到HTML后就不会再变化,用户输入换行时服务端逻辑不会重新执行,所以无法动态调整行数。
第一步:调整ERB模板
给text_area添加专属类名用于JS选中,初始rows固定为1即可:
<%= form.text_area :body, rows: 1, value: @direct_message.body, class: "form-control auto-resize-textarea", placeholder: "", autocomplete: 'off' %>
第二步:添加自适应高度的JS逻辑
原理是监听输入框内容变化,动态将输入框高度设置为内容实际滚动高度:
// 适配普通页面加载,如果你使用Rails 7+的Turbo,将DOMContentLoaded改为turbo:load即可 document.addEventListener('DOMContentLoaded', () => { // 选中所有需要自适应的文本框 const autoResizeTextareas = document.querySelectorAll('.auto-resize-textarea') const adjustHeight = (el) => { // 先重置高度为auto,保证scrollHeight计算准确 el.style.height = 'auto' // 高度设置为内容实际高度,可根据需要加2-4px偏移避免内容挤压 el.style.height = `${el.scrollHeight}px` } autoResizeTextareas.forEach(textarea => { // 页面加载时先执行一次,适配已有历史内容的高度 adjustHeight(textarea) // 监听用户输入事件,动态调整高度 textarea.addEventListener('input', () => adjustHeight(textarea)) }) })
第三步:可选CSS优化
可以添加CSS限制最大高度,避免文本框过高:
.auto-resize-textarea { resize: none; /* 禁止用户手动拖拽调整大小,不需要可删除 */ max-height: 240px; /* 自定义最大高度,超过后自动出现滚动条 */ overflow-y: auto; }
内容的提问来源于stack exchange,提问作者Mervyn Lee
相关产品推荐
相关产品推荐

