1

I have javascript script that creates the same div everytime the user clicks enter and then set the event listener to the new input in the new div.

example:

//creates the container, text and input for the new line
function createNewUserInputLine() {
    var body = document.body;
    var inputLine = document.createElement("div");
    var inputLineLabel = document.createElement("p");
    var inputLineTextbox = document.createElement("input");
    var labelText = document.createTextNode("Click enter to display Hello World");
    inputLine.className = "input-line";
    inputLineLabel.className = "input-label"
    inputLineTextbox.className = "user-input"
    inputLineLabel.appendChild(labelText);
    inputLine.appendChild(inputLineLabel);
    inputLine.appendChild(inputLineTextbox);
    body.appendChild(inputLine);
    addListenerForUserInput();
}

//adds an event listener for the newest input line to capture when 
//the user clicks the enter key, and removes the listener and disables
//the input from the last input line
function addListenerForUserInput() {
    var userInputArray = document.getElementsByClassName("user-input");
    var activeUserInput = userInputArray[userInputArray.length - 1];
    var unactiveUserInput = userInputArray[userInputArray.length - 2];

    function captureEnterPress(event) {
        if (event.key === "Enter" || event.keyCode === 13) {
            event.preventDefault();
            createOutputLine();
        }
    }

    if (userInputArray.length > 1) {
        unactiveUserInput.removeEventListener("keyup", captureEnterPress);
        unactiveUserInput.disabled = true;
    }

    activeUserInput.focus();
    activeUserInput.addEventListener("keyup", captureEnterPress);
}

//creates the output line
function createOutputLine() {
    var element = document.body;
    var br = document.createElement("br");
    var outputLine = document.createElement("p");
    var outputLineText = document.createTextNode("Hello World!");
    outputLine.className = "output-line";
    outputLine.appendChild(outputLineText);
    element.appendChild(outputLine);
    element.appendChild(br);
    createNewUserInputLine();
}

//when the page is finished loading it prints the first line
onload = () => {
    createNewUserInputLine();
}

The html file is empty and the first div is created in the onload method. Is this the right way to do it, or should I create the first div in the html and then attach the event listener in the javascript and that will add the new divs each time the user clicks enter?

5
  • 2
    In general, embedding one language in another is going to be suboptimal with respect to maintainability. Instead of embedding SQL in your C# code, use stored procedures; instead of embedding HTML in your Javascript, use the HTML file. This makes it easier when you want to change something, e.g. what if you want to style that div?
    – John Wu
    Commented Sep 24, 2021 at 17:36
  • To follow up on the @JohnWu comment, if that DIV is somehow "really special" and you really don't want other parts of the code to know about it, it makes some sense to create it in the JS code. However, in general, creating in the HTML is "better" and exposes the DIV to use by others.
    – user949300
    Commented Sep 24, 2021 at 18:23
  • Great point! I update the question though, to explain why this might not be the proper solution in my case. Commented Sep 24, 2021 at 19:08
  • The other ones will only be loaded in my answer if the user chooses to. Hard code the initial one. Use JavaScript event delegation when deciding to show another one. Commented Sep 24, 2021 at 19:08
  • @GregBurghardt, I think I got it now. Thanks! Commented Sep 24, 2021 at 19:13

2 Answers 2

1

In this case, the JavaScript being executed onload is just hard coding the HTML, essentially. There really is no logic being executed. JavaScript is just building the DOM tree to populate it with some initial set of nodes. We already have a language for that, and it is much more expressive: HTML.

In this case, since there is no logic to creating the DOM nodes, you are much better off writing it as HTML. Those elements will appear to the end user right as the page loads. The page will not shift around as the browser re-renders the page after the onload event, which is a much less jarring experience for the end user.

There is a bit of a snag when it comes to attaching event handlers, but this can be easily solved with JavaScript event delegation.

I don't often rewrite code in an answer, but I think it is justified in this case to give a clear visual:

<div class="input-line">
  <p class="input-label">
    Click enter to display Hello World
  </p>

  <input type="text" class="user-input" autofocus>
</div>

<script>
    function handleKeyUp(event) {
        if (event.target.classList.contains("user-input")) {
            // your original event handler code goes here
        }
    }

    document.documentElement.addEventListener("keyup", handleKeyUp, false);
</script>

With event delegation, you no longer need to attach event handlers to new elements created and appended to the DOM tree by JavaScript.

So, to answer your question:

  1. Create the initial tags using HTML — that's what HTML is meant for.
  2. Use event delegation so you don't have to attach event handlers at a specific time.

For event delegation, I prefer using the document.documentElement object. This points to the <html> tag, and is available to JavaScript the moment your code begins executing.

0

Maybe not "better" but "more modern",

First off, let me introduce you to "Template Literals"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Once your mind is unblown you then need to check out "SPA frameworks", pick one

2
  • I know what 'Template Literals' are, but how does it answer my question? Commented Sep 26, 2021 at 6:59
  • "is there a better way to do it" yes
    – Ewan
    Commented Sep 26, 2021 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.