如何计算textarea中预填充文本的行数(含手动/自动换行)
实现文本复制到Textarea并统计包含隐式/显式换行的行数
我来帮你搞定这个需求!要实现把<p>标签的文本复制到textarea,还要统计包含手动换行和自动换行的总行数并更新页面上的数字,咱们一步步来:
1. 修正文本复制的触发逻辑
你原来的代码是页面加载完成就执行复制,但需求是点击模态框时才复制,所以得把代码绑定到模态框的点击事件上。假设你的模态框选择器是.modal,代码可以改成这样:
$(function() { // 绑定模态框点击事件 $('.modal').on('click', function() { // 复制p标签的文本到textarea const tempText = $('.messageContent p').text(); $('#messageBox').val(tempText); // 复制完成后立即统计行数并更新 updateLineCount(); }); });
2. 实现包含隐式/显式换行的行数统计
要统计textarea里的所有行数(包括自动换行的隐式行),最准确的方式是创建一个和textarea排版完全一致的隐藏元素,模拟文本的换行情况,然后计算总行数。
完整代码实现
HTML部分(保留你的原有结构,加上隐藏的镜像div):
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="messageContent"> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in </p> </div> <!-- 假设这是你的模态框 --> <div class="modal" style="border:1px solid #ccc; padding:10px; cursor:pointer;">点击打开模态框</div> <textarea cols="50" rows='10' id="messageBox" style="width:400px; font-family:Arial; font-size:14px; line-height:1.5; padding:8px;"></textarea> <p><span id="lineCount">0</span> line</p> <!-- 隐藏的镜像div,用来模拟textarea排版 --> <div id="textMirror" style="visibility:hidden; position:absolute; top:0; left:0; width:400px; font-family:Arial; font-size:14px; line-height:1.5; padding:8px; white-space:pre-wrap; word-wrap:break-word;"></div>
JavaScript部分(包含复制和统计逻辑):
$(function() { // 绑定模态框点击事件 $('.modal').on('click', function() { const tempText = $('.messageContent p').text(); $('#messageBox').val(tempText); // 复制后立即更新行数 updateLineCount(); }); // 监听textarea的输入变化,实时更新行数 $('#messageBox').on('input', function() { updateLineCount(); }); // 核心:计算并更新行数的函数 function updateLineCount() { const textarea = $('#messageBox')[0]; const mirror = $('#textMirror')[0]; const lineCountEl = $('#lineCount'); // 把textarea的内容转成适合div的格式:替换\n为<br>,同时保留空格 const content = textarea.value.replace(/\n/g, '<br>'); mirror.innerHTML = content; // 计算单行高度:第一次加载时获取,之后复用 if (!window.lineHeight) { window.lineHeight = parseInt($(mirror).css('line-height')); // 如果line-height是normal,手动计算 if (isNaN(window.lineHeight)) { const temp = $('<span>test</span>').appendTo(mirror); window.lineHeight = temp.height(); temp.remove(); } } // 总行数 = 总高度 / 单行高度 const totalLines = Math.round(mirror.offsetHeight / window.lineHeight); // 更新页面上的数字,顺便处理单复数 lineCountEl.text(totalLines); lineCountEl.parent().text(`${totalLines} ${totalLines === 1 ? 'line' : 'lines'}`); } });
3. 额外优化说明
上面的代码加了input事件监听,用户手动修改textarea内容时,行数会实时更新,体验更流畅。
为什么用镜像div?
因为textarea的自动换行是浏览器根据其宽度、字体等样式自动计算的,只统计\n的数量只能得到手动换行的显式行数,无法统计自动换行的隐式行。用镜像元素可以完全模拟textarea的排版,得到最准确的总行数。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

