0

Hello I'm pretty new to JS and HTML and was trying to make something close to a text editor component like Monaco Editor.
How it works-
function Ventify() takes an element and adds a gutter and a textarea. So I made an if statement in this function that checks the no of lines in the textarea and create gutter lines accordingly. the problem I experienced while doing this was that the function only numbers the lines of the text when it was loaded because the function ended. Is there a way in which I can make the function/if statement never end.
Here is a codepen for the project: https://codepen.io/chrismg/pen/qgxOxg .
JS(with JQuery):

function Ventify(element){
    element.style.display="flex";
    element.style.flexDirection = "row";
    var gutter = document.createElement("div");
    var textarea = document.createElement("textarea");
    gutter.className = "gutter";
    textarea.className = "ventiEditor";
    gutter.style.width = "100px";
    gutter.style.height = "100%";
    gutter.style.backgroundColor = "#1d252c";

    textarea.style.width = "calc(100% - 100px)";
    textarea.style.overflowY= "scroll";
    textarea.style.whiteSpace = "pre";
    textarea.style.resize = "none";
    textarea.style.height = "100%";
    textarea.style.margin = "0px 0px 0px 0px"
    textarea.style.border = "0px solid rgb(255,255,255)"
    textarea.style.backgroundColor = "#1d252c";
    textarea.value = "\n\n\n\n";
    element.appendChild(gutter);
    element.appendChild(textarea);
    if(gutter.childNodes.length != $(textarea).val().split("\n").length){
        while(gutter.childNodes.length < $(textarea).val().split("\n").length){
            var gutterChild = document.createElement("div");
            gutterChild.style.width = "100%";
            gutterChild.style.color = "rgba(58,74,88,1)"
            gutterChild.style.textAlign = "center";
            gutter.appendChild(gutterChild);
            gutterChild.innerHTML = `${gutter.childNodes.length}`
        }
    }
}
    Ventify(document.getElementsByClassName("container")[0])

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Ground</title>
    <style>
        html,body{
            height: 100%;
            margin: 0px 0px 0px 0px;
        }
        .container{
            height: 50%;
        }
    </style>
</head>
<body>
    <div class="container"></div>
</body>
</html>
Apoqlite
  • 239
  • 2
  • 21
  • 1
    You need to attach an event listener to your codes. If you add dynamic content to textarea you may use a callback function for data load event. – Ali Sheikhpour Feb 08 '19 at 16:23

3 Answers3

0

A better approach will be using a onKeydown ( or similar events ) event on a input or textarea. Like in below example

function handle(){
  let element = document.getElementById('inp').value;
  console.log(element, 'called on change')
}
<input id='inp' onKeydown=handle() />

In your code can use setInterval. And clearinterval when you want to stop.

setInterval(Ventify(document.getElementsByClassName("container")[0]),200)

Codepen

Code Maniac
  • 37,143
  • 5
  • 39
  • 60
0

You can use input event attached to <textarea> element to perform a task at user input. See How to continually add typed characters to a variable?.

If you are trying to check if an element childList or attributes have changed you can use MutationObserver. See call function on change of value inside <p> tag.

guest271314
  • 1
  • 15
  • 104
  • 177
  • Thanks that worked. However I'm experiencing a small problem while doing so probably due to my code: the second while statement doesn't work at all and instead slows the page down, so the gutter can increase in no of lines but not decrease. – Apoqlite Feb 08 '19 at 16:46
  • @Apoqlite Is the `while` loop necessary? – guest271314 Feb 08 '19 at 16:49
  • The while loop isn't neccessary it can be replaced with an if statement, sorry abt that. I got it to work, thanks! – Apoqlite Feb 08 '19 at 16:57
0

You can use the onchange event to fire your function every time the user updates the content.

const element = document.getElementsByClassName("container")[0];
element.onchange = (event) => Ventify(event.target, 200);
RickTakes
  • 1,197
  • 1
  • 9
  • 14