Reputation: 707
Let me clarify, my below code is doing what I want.
I'm working on a simple todo app. Right now, everytime the button is clicked on the page, it runs the createListElem() function. The first line of code inside this function appends our ul element to the body. However, it doesn't repeatedly add new ul elements when the button is clicked. It only adds li elements to that ul element.
Let me again clarify, that is fine and is what I want it to do.
Everytime we hit that button, we run the function. So in theory, everytime we hit that button, a new ul_node is appended to the body? Or is it because I intialized the variable holding the ul_node outside the function, it doesn't append a new ul_node?
Basically my question is: Why when we click that button, the function appends one ul element to the page, rather than a ul element every button click?
Hope I'm clear! My code is below
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<title>Nick's Todo List</title>
</head>
<body>
<h1 class="main-header">Nick's Todo List</h1>
<div class="input-container">
<input id="input-box" type="text" value="bro bro">
<input onclick="createListElem()" id="add-btn" type="button">
<select name="task-completion" id="task-completion">
<option value="All">All</option>
<option value="Completed">Completed</option>
<option value="Uncompleted">Uncompleted</option>
</select>
</div>
<script src="./app.js"></script>
</body>
</html>
JavaScript
const ul_node = document.createElement("ul");
function createListElem() {
document.body.appendChild(ul_node);
const box_value = document.getElementById('input-box').value;
const task = document.createTextNode(box_value);
const li_node = document.createElement('li');
li_node.appendChild(task)
ul_node.appendChild(li_node)
}
Upvotes: 0
Views: 99
Reputation: 65835
Everytime we hit that button, we run the function. So in theory, everytime we hit that button, a new ul_node is appended to the body? Or is it because I intialized the variable holding the ul_node outside the function, it doesn't append a new ul_node?
Yes, that's correct. The code to create the ul
element exists outside of your function and is executed only once. It's the code within your callback function that runs every time you click the button. Now, the first time you click the button the new ul
is appended to the body
, but from there on, when you ask for the ul
to be appended to the body, you are asking for the one that already exists to be appended and when that happens, append just moves the element from where it is to where you told it to go. Since where it is and where you are telling it to go are the same location, no new ul
seems to appear.
If you want to create a new ul
to add below the existing one each time, you'll need to move the createElement
line into the function.
Upvotes: 2
Reputation: 1
When you use parentElement.appendChild(element)
the existing element
is moved from its current location to the new location
The first time, this results in the element being added to the DOM
Second and subsequent calls simply moves the element from its current location in the DOM to the new location - in this case back to where it was, since it already is the last child of document.body
The only time this code could be a problem is if other elements are appended after this UL
... in that case, calling createListElem
would move the UL element after those elements
One way to avoid this is to check if ul
is already in the DOM - i.e. it has a .parentElement
(or .parentNode
) and only append it if it does not
const ul_node = document.createElement("ul");
function createListElem() {
if (!ul_node.parentElement) {
document.body.appendChild(ul_node);
}
// ... etc
}
Upvotes: 2