js实现多行文本控件textarea,根据文本内容自适应窗口全部显示
概述
本人在使用html控件textarea,多行显示的时候,希望根据后台实际的文本,来全部显示文本内容,而不用再去操作滚动条查看全部文本。
本功能实现的难点在于,计算当前文本显示有多少行。
软件环境
编辑器:Visual studio code,版本1.93.1
浏览器1:Microsoft Edge,版本129.0.2792.52,
浏览器2:Google Chrome,版本126.0.6478.115
前端html代码
<textarea id="idOutputResult" style="text-align: left;font-size: 18px;vertical-align: bottom" type="text" rows="1" cols="50" readonly onchange="OnChangeOutputResultText(this)"></textarea>
计算显示行数原理
下面是本人总结的实现原理,一点点弯弯绕绕,如果不想看直接把后面一节代码考过去用也行。
1、textarea有一个属性cols,表示每一行最多的文本字符个数,如本例是50个字符:cols=“50”。
2、文本字符要考虑ascii字符(ascii值小于128的),和汉字字符。一个ascii字符占一个字符位,一个汉字字符占两个字符位。
3、汉字字符和ascii字符混合,在一行临界值情况。比如cols=4,一行可以2个汉字,或者一行可以1个汉字加2个ascii字符。经两个浏览器实际操作有一种特殊情况,一行可以2个汉字加1个ascii字符也能挤进去。
4、\r\n算一个换行,单独\n算一个换行,单独一个\r也算一个换行。换行之后要字符重新计数。
计算显示行数代码
function CommonCalTextareaRows(text, ctrlCols) {var i = 0;var startIndex = 0;var rows = 0;startIndex = 0;for (i = 0; i < text.length; i++) {if (text.charCodeAt(i) >= 256) {//汉字算两个,要考虑半个汉字字符问题/*if ((startIndex + 1) >= ctrlCols) {rows++;startIndex = 0;} else {startIndex++;}startIndex++;*///会挤进去startIndex += 2;} else if (text[i] == '\r') {if (i + 1 < text.length && text[i + 1] == '\n') {i++;}rows++;startIndex = 0;continue;} else if (text[i] == '\n') {rows++;startIndex = 0;continue;} else {startIndex++;}if (startIndex >= ctrlCols) {rows++;startIndex = 0;}}if (startIndex > 0) {rows++;}return rows;
}
自适应窗口调用
在textarea文本改变的地方调用,本人是后台收到ajax回调函数,用setTimeout异步调用,如下,
setTimeout(function(){OnChangeOutputResultText(document.getElementById("idOutputResult"));}, 0);
function OnChangeOutputResultText(obj) {var rowCnt = CommonCalTextareaRows(obj.value, obj.cols);obj.rows = rowCnt;
}
在前面的前端html代码中onchange消息,也有调用
οnchange="OnChangeOutputResultText(this)"
测试效果
下面是本人计算数据2的1024次方,对后台返回的大的数据,计算出行数,动态的调整窗口显示出来,本人认为效果还可以,如下,