65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 textarea 实现 HTML 行号

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2019 年 7 月 26 日

CPOL

2分钟阅读

viewsIcon

34279

downloadIcon

669

使用 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 &lt;textarea&gt;</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(用于滚动同步)
  • onclickonkeyup 事件(用于读取当前位置/选区)

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 )基本上是读取一个 textareascrollTop 属性,并将此属性设置为另一个 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 对象的 selectionStartselectionEnd 属性(也适用于其他一些 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 日:初始版本
使用 textarea 实现 HTML 行号 - CodeProject - 代码之家
© . All rights reserved.