如何限制textarea达到行数上限后禁止输入?
解决textarea自动换行导致行数超出限制的问题
问题背景
需限制textarea的总行数等于resizable-div元素的offsetHeight除以24,目前仅能阻止用户手动按回车新增行数,但文本溢出textarea宽度自动换行时,仍会产生新行导致行数超出限制。由于resizable-div支持调整大小,无法通过固定字符数限制或固定高度隐藏溢出的方式解决。
解决方案核心
现有代码仅通过换行符\n分割统计行数,无法识别自动换行产生的行。需改为统计textarea实际渲染的行数,可以通过getClientRects()方法获取每行文本的矩形区域,精准统计行数,再进行内容截断。
修改后的完整代码
HTML
<div id="container"> <div id="resizable-div"> <div></div> </div> <div class="text-content"> <textarea id="text-area"></textarea> </div> </div>
CSS(补充必要样式)
#text-area { line-height: 24px; /* 与行数计算基准一致 */ resize: none; overflow: hidden; box-sizing: border-box; width: 100%; } #resizable-div { resize: vertical; overflow: auto; border: 1px solid #ccc; }
JavaScript
let resizeDiv = document.getElementById('resizable-div'); let textArea = document.getElementById('text-area'); function adjustResizeDivHeight(){ if (resizeDiv.offsetHeight % 24 !== 0) { resizeDiv.style.height = `${(Math.round(resizeDiv.offsetHeight / 24) * 24) - 48}px`; } } function syncTextareaSettings() { const maxLines = Math.floor(resizeDiv.offsetHeight / 24); // 同步textarea高度,刚好容纳maxLines行 textArea.style.height = `${maxLines * 24}px`; } // 初始化及调整div后的同步操作 window.addEventListener('load', () => { adjustResizeDivHeight(); syncTextareaSettings(); }); resizeDiv.addEventListener('mouseup', () => { adjustResizeDivHeight(); syncTextareaSettings(); }); textArea.addEventListener("input", function(e) { const maxLines = Math.floor(resizeDiv.offsetHeight / 24); // 获取实际渲染的行数(包括自动换行) const actualRenderedLines = this.getClientRects().length; if (actualRenderedLines > maxLines) { // 逐字符截断内容,直到行数符合限制 while (this.getClientRects().length > maxLines && this.value.length > 0) { this.value = this.value.slice(0, -1); // 保持光标在内容末尾 this.setSelectionRange(this.value.length, this.value.length); } e.preventDefault(); } });
关键逻辑说明
syncTextareaSettings:同步textarea的高度与最大允许行数对应的高度,确保textarea可视区域刚好容纳maxLines行,避免出现滚动条。getClientRects():返回textarea中每一行文本的DOMRect集合,集合的长度即为实际渲染的行数,精准识别自动换行产生的行。- 逐字符截断:当实际行数超出限制时,从内容末尾逐字符删除,直到行数符合要求,同时重置光标位置到末尾,保证用户输入体验。
内容的提问来源于stack exchange,提问作者pumpchief
相关产品推荐
相关产品推荐

