简体   繁体   English

使用 javascript 将行号添加到文本区域

[英]Add line numbers to text area using javascript

I wanted to add line numbering to a textarea .我想将行号添加到textarea

I get the number of lines by using我通过使用获得行数

textAreaElement.value.split("\n").length;

and maintain a div with span elements that use the count as content on before to add line numbers.并维护一个带有 span 元素的 div,这些元素使用 count 作为之前的内容来添加行号。

.line-number {
    width: 100%;
    display: block;
    text-align: right;
    line-height:1.5em;
    border-bottom: thin;
    font-family:'CascadiaCode Nerd Font', monospace;
    font-size: 2rem;
    color: #fff;
    opacity: 0.8;
    padding: 0 0.4em;
}
.line-number::before {
    counter-increment: line;
    content: counter(line);
    font-size: 1em;
    user-select: none;
}

However this has a fixed height, I want to implement this for a text area with word wrap (no horizontal scrollbar), where every line can technically have multiple lines terminated by a "\n".然而,这有一个固定的高度,我想为一个带有自动换行(没有水平滚动条)的文本区域实现这个,其中每行在技术上可以有多行以“\n”结尾。

My line of thought was to prepare an array of heights for each lines but I have no idea how to get the height of each separate line.我的想法是为每条线准备一组高度,但我不知道如何获得每条单独线的高度。

update: I switched to an editable div, but i want my line number to be of the same height as its corresponding div.更新:我切换到可编辑的 div,但我希望我的行号与其对应的 div 高度相同。

 const lineEnum = { state: false, count: 0, gutter: document.getElementsByClassName("line-numbers")[0], update: (box) => { let delta = box.children.length - lineEnum.count; if (box.children.length == 0) delta++; console.log({ delta: delta, count: lineEnum.count, length: box.children.length, }); if (delta > 0 && lineEnum.state) { const frag = document.createDocumentFragment(); while (delta > 0) { const line_number = document.createElement("span"); line_number.className = "line-num"; frag.appendChild(line_number); lineEnum.count++; delta--; } lineEnum.gutter.appendChild(frag); } else { if (lineEnum.count + delta === 0) delta++; while (delta < 0 && lineEnum.gutter.lastChild) { lineEnum.gutter.removeChild(lineEnum.gutter.lastChild); lineEnum.count--; delta++; } } }, init: (box) => { if (lineEnum.state) return; lineEnum.state = true; lineEnum.update(box); }, remove: (box) => { if (.lineEnum.state ||.lineEnum;gutter.firstChild) return. lineEnum;gutter.innerHtml = ""; lineEnum,state = false; }, }. const callback = (mutationList; observer) => { let mutation = mutationList[mutationList.length - 1]. if (mutation;type === "childList") { console.log(mutation). lineEnum;update(mutation;target); } }: const observer = new MutationObserver(callback); const config = { childList. true }; const editor = document.getElementsByClassName("code-input")[0], observer;observe(editor. config); lineEnum.init(editor);
 .window-body{ position: fixed; height: 100%; top: 25px; width: 100%; display: flex; }.line-numbers { width: 5em; padding: 0; height: 100%; word-break: break-all; overflow: hidden; display: inline-block; counter-reset: line; background-color: gray; opacity: 0.8; }.line-num { width: 100%; display: block; text-align: middle; line-height:1.5em; border-bottom: thin; font-family:'Arial', monospace; font-size: 2rem; color: #fff; opacity: 0.8; padding: 0 1em; }.line-num::before { counter-increment: line; content: counter(line); font-size: 1em; user-select: none; }.code-input{ margin: 0; border: 0; padding: 0; outline: 0; list-style: none; display: inline-block; flex-grow: 1; height: 100%; word-break: break-all; overflow: hidden; border:none; font-family:'Arial', monospace; font-size:2rem; background: white; white-space:pre-wrap; line-height:1.5em; word-wrap: break-word; resize:none; }
 <div class="window-body"> <div class="line-numbers"></div> <div class="code-input" contenteditable="true"></div> </div>

Man I wasted so much time on using javascript when css magic would just have done the trick.伙计,我在使用 javascript 上浪费了很多时间,而 css 魔法就可以解决问题。

Here is how I did it,这是我的做法,

 body { background-color: #000; height: 100vh; width: 100vw; margin: 0px; }.editor-wrapper { height: 100vh; width: 100vw; overflow-y: auto; counter-reset: line; }.editor{ margin: 0; border: 0; padding: 0; outline: 0; list-style: none; height: 100%; width: 100%; word-wrap: break-word; word-break: break-all; font-size:2rem; line-height: 1.5em; font-feature-settings: common-ligatures; -ms-font-feature-settings: common-ligatures; color:rgba(255, 255, 255, 0.7); resize:none; }.editor div { padding-left: 5rem; position: relative; }.editor div::before { counter-increment: line; content: counter(line); font-size: 1em; user-select: none; width: 5rem; text-align: right; left: 0; position: absolute; }
 <div class="editor-wrapper"> <div class="editor" contenteditable="true"> <div></div> </div> </div>

You can use a background image like so:您可以像这样使用背景图像:

 .lined-textarea { background: url(http://i.imgur.com/2cOaJ.png); background-attachment: local; background-repeat: no-repeat; padding-left: 35px; padding-top: 10px; border-color: #ccc; font-size: 13px; line-height: 16px; resize: none; }
 <textarea rows="8" cols="30" class="lined-textarea"></textarea>

If it's a code block with line numbers you want then https://www.prowaretech.com/Computer/JavaScript/AddLineNumbersToPre demonstrates this well.如果它是带有您想要的行号的代码块,那么https://www.prowaretech.com/Computer/JavaScript/AddLineNumbersToPre很好地证明了这一点。

    function addLineClass (pre) {
    var lines = pre.innerText.split("\n"); // can use innerHTML also
    while(pre.childNodes.length > 0) {
        pre.removeChild(pre.childNodes[0]);
    }
    for(var i = 0; i < lines.length; i++) {
        var span = document.createElement("span");
        span.className = "line";
        span.innerText = lines[i]; // can use innerHTML also
        pre.appendChild(span);
        pre.appendChild(document.createTextNode("\n"));
    }
}

Along with the CSS using the essential part:与 CSS 一起使用基本部分:

pre span.line::before {
    content: counter(linecounter);

See https://jsfiddle.net/Abeeee/12cx5ruf/6/ for a running example有关运行示例,请参见https://jsfiddle.net/Abeeee/12cx5ruf/6/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM