使用 textarea 实现 HTML 行号





5.00/5 (4投票s)
使用 textarea 实现 HTML 行号
引言
这是一个在 HTML 页面中为文本(例如,代码编写)添加行号的简单解决方案。由于据我所知,HTML 本身没有提供此功能的元素,我创建了一个小而简单的代码,可以完美有效地完成这项任务,即使对于非常长的文本也是如此。
它使用了 2 个 textarea
元素,右侧用于编写或粘贴文本,左侧是只读的,并由 JavaScript 填充,显示文本的行号。这两个 textarea
元素在 JS 代码中实现了滚动同步。下方还有一个元素,显示文本中的当前位置/选区。
Using the Code
HTML 部分非常短,包含 2 个 textarea
元素,它们被包装在一个 div
中;用于编写的 textarea
与用于显示当前位置/选区的 input
元素一起包装在 span
中 - 这纯粹是为了方便从 JavaScript 代码中访问这些元素。
<body onload="initialize()" onresize="onresize_sub()">
<h1>Line numbering using <textarea></h1>
<div>
<textarea class="rownr" rows="20"
cols="3" value="1" readonly></textarea>
<span>
<textarea class="txt" rows="20"
cols="150" nowrap="nowrap" wrap="off"
autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false"
onclick="selectionchanged(this)"
onkeyup="keyup(this,event)" oninput="input_changed(this)"
onscroll="scroll_changed(this)"></textarea><br/><br/>
<label>Current position:
</label><input id="sel_in" style="border-style:none" readonly>
</span>
</div>
</body>
CSS 也非常简单,包含一些颜色和文本对齐。
<style>
.rownr {overflow-y: hidden; background-color: rgb(105,105,105); color: white;
text-align: right; vertical-align:top}
.txt {width: 95%; overflow-x: scroll}
</style>
主要的 textarea
使用事件处理程序来处理
oninput
(用于填充行号)onscroll
(用于滚动同步)onclick
和onkeyup
事件(用于读取当前位置/选区)
Oninput 事件处理程序
当在 textarea
中输入一些文本时,会调用函数 input_changed
function input_changed(obj_txt)
{
obj_rownr = obj_txt.parentElement.parentElement.getElementsByTagName('textarea')[0];
cntline = count_lines(obj_txt.value);
if(cntline == 0) cntline = 1;
tmp_arr = obj_rownr.value.split('\n');
cntline_old = parseInt(tmp_arr[tmp_arr.length - 1], 10);
// if there was a change in line count
if(cntline != cntline_old)
{
obj_rownr.cols = cntline.toString().length; // new width of txt_rownr
populate_rownr(obj_rownr, cntline);
scroll_changed(obj_txt);
}
selectionchanged(obj_txt);
}
此函数调用另一个函数 count_lines
来计算文本中的行数(通过使用 \n
分割文本并计算结果数组的元素数量)。然后,如果行数确实发生了变化,则会重新填充 rownr textarea
。
Onscroll 事件处理程序
onscroll
事件处理程序(scroll_changed
)基本上是读取一个 textarea
的 scrollTop
属性,并将此属性设置为另一个 textarea
。 (此函数也可以与任何 2 个可滚动的 HTML 元素一起工作。)
function scroll_changed(obj_txt)
{
obj_rownr = obj_txt.parentElement.parentElement.getElementsByTagName('textarea')[0];
scrollsync(obj_txt,obj_rownr);
}
function scrollsync(obj1, obj2)
{
// scroll text in object id1 the same as object id2
obj2.scrollTop = obj1.scrollTop;
}
Onclick 和 onkeyup 事件处理程序
当单击 textarea
时,会调用 selectionchanged
函数。
function selectionchanged(obj)
{
var substr = obj.value.substring(0,obj.selectionStart).split('\n');
var row = substr.length;
var col = substr[substr.length-1].length;
var tmpstr = '(' + row.toString() + ',' + col.toString() + ')';
// if selection spans over
if(obj.selectionStart != obj.selectionEnd)
{
substr = obj.value.substring(obj.selectionStart, obj.selectionEnd).split('\n');
row += substr.length - 1;
col = substr[substr.length-1].length;
tmpstr += ' - (' + row.toString() + ',' + col.toString() + ')';
}
obj.parentElement.getElementsByTagName('input')[0].value = tmpstr;
}
这个简单的函数使用 textarea
对象的 selectionStart
和 selectionEnd
属性(也适用于其他一些 HTML 元素)来计算片段所在的当前行和列。
为了处理键盘上的箭头键,以及 Home、End、Page Up 和 Page Down 键,还有一个用于 keyUp
事件的处理函数。此函数除了在按下这些键时调用 selectionchanged
函数外,什么也不做。
function keyup(obj, e)
{
if(e.keyCode >= 33 && e.keyCode <= 40) // arrows ; home ; end ; page up/down
selectionchanged(obj, e.keyCode);
}
历史
- 2019 年 7 月 26 日:初始版本