Coding, Insights, and Digital Discoveries 👩🏻💻
From Stay-at-Home Mom to a Developer After 50
I coded a To-Do-List app using vanilla javascript. My goal for this project is to refresh my knowledge of vanilla JavaScript, as frequent use of React.js and Next.js can make clean JavaScript coding habits feel unfamiliar.
During the development process, I needed to dynamically generate elements when adding new tasks. This made me realize that even basic DOM knowledge is worth revisiting.
Let's compare two functions that dynamically create an <li>
element for listing new tasks in the UI.
The first function is as follows:
function createTaskElement(task) {
const li = document.createElement("li");
li.innerHTML = `
<input type="checkbox" class="task-checkbox" ${task.completed ? "checked" : ""}>
<span class="task-text">${task.text}</span>
`;
if (task.completed) {
completedTaskList.appendChild(li);
} else {
taskList.appendChild(li);
}
}
This version uses innerHTML
to add he task text. However, this approach has several drawbacks:
task.text
contains malicious code, it can introduce an XSS (Cross-Site Scripting) vulnerability. For security reasons, this method is not recommended in production.innerHTML
parses HTML strings, which is generally slower than direct DOM manipulation.Now, let's check out an improved version:
function createTaskElement(task) {
// Create <li> element
const li = document.createElement("li");
// Create checkbox
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.className = "task-checkbox";
checkbox.checked = task.completed;
checkbox.addEventListener("change", (e) => {
animateTaskCompletion(li, e.target.checked);
updateTaskStatus(task.text, e.target.checked);
});
// Create task text span
const taskText = document.createElement("span");
taskText.className = "task-text";
taskText.textContent = task.text;
// Append elements to <li>
li.append(checkbox, taskText)
// Append <li> to the correct list
(task.completed ? completedTaskList : taskList).appendChild(li);
return li;
}
textContent
, which automatically escapes special characters, making it safer against XSS attacks.createElement()
directly manipulates the DOM, which is more efficient than using innerHTML
to parse and insert HTML strings.return li
statement, making it more flexible. Returning the element allows it to be referenced later, like in the following example:const newTaskElement = createTaskElement(task);
// Want to do something with the element later
newTaskElement.scrollIntoView();
By returning the newly created element, this function adheres to the principle that if a function creates something, it should return it. This improves testability and allows for method chaining if needed.
This modular approach provides better security, performance, maintainability, and flexibility—making it the preferred choice for this vanilla JavaScript project.