'Toggle dark mode - Problem with newly created elements
I want to make JS dark mode toggle with click event but it works with HTML elements but it doesn't work with created elements with JavaScript using DOM.
let body = document.querySelector(`body`);
let input = document.querySelector(`.input`);
let addBtn = document.querySelector(`.add`);
let form = document.querySelector(`.form`);
let container = document.querySelector(`.tasks`);
form.addEventListener(`submit`, (e) => {
e.preventDefault();
const task = input.value;
if (!task) {
window.alert(`please fill the input!`);
} else {
const taskEl = document.createElement(`div`);
taskEl.classList.add(`task`);
const taskContentEl = document.createElement(`div`);
taskContentEl.appendChild(document.createTextNode(task));
taskEl.appendChild(taskContentEl);
container.appendChild(taskEl);
input.value = ``;
}
});
function darkMode() {
let darkBtn = document.querySelector(`.btn`);
darkBtn.onclick = () => {
form.classList.toggle(`formDark`);
input.classList.toggle(`inputDark`);
body.classList.toggle(`bodyDark`);
//here is the code that's not works
taskEl.classList.toggle(`inputDark`);
};
}
darkMode();
<button type="button" class="btn">Dark mode</button>
<form class="form">
<input>
</form>
<div class="tasks"></div>
Solution 1:[1]
See this answer: Dark Mode: toggle using JavaScript on how to implement Dark mode toggle using LocalStorage as example.
Toggle dark mode styles on present or future elements?
Simple. Don't use a specific JS list of all your elements to toggle classes from.
Just toggle a "dark"
class on the body
element. Then, use CSS to style everything else:
document.body.classList.toggle("dark");
.dark .input {}
.dark .add {}
.dark .someFutureElement {}
Example with a remake of your code:
// DOM utility functions:
const el = (sel, par) => (par || document).querySelector(sel);
const els = (sel, par) => (par || document).querySelectorAll(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
// App: Tasks
const elInput = el(`#taskInput`);
const elAdd = el(`#taskAdd`);
const elForm = el(`#taskForm`);
const elTasks = el(`#tasks`);
const createTask = (task) => {
tasks.push(task);
const elTask = elNew(`li`, {textContent: task, className: "task"});
elTasks.append(elTask);
};
elForm.addEventListener(`submit`, (evt) => {
evt.preventDefault();
const task = elInput.value.trim(); // Trim from whitespaces!
if (!task) return alert(`Please, fill the input!`);
createTask(task);
elInput.value = ``;
});
// Init: Populate existing tasks
const tasks = ["Drink coffee", "Develop some app"];
tasks.forEach(createTask);
// App: Dark mode
const elBody = el(`body`);
const elToggleDark = el(`#toggleDark`);
elToggleDark.addEventListener("click", () => {
elBody.classList.toggle("dark", elToggleDark.checked);
});
.dark {
background: #333;
color: #fff;
}
.dark #taskInput {
background: rgba(255,255,255,0.2);
color: #fff;
}
.dark ol {
border: 1px solid rgba(255,255,255,0.2);
}
<label><input type="checkbox" id="toggleDark"> Toggle Dark Mode</label>
<form id="taskForm">
<input id="taskInput" type="text" placeholder="Task...">
<button id="taskAdd">Add</button>
</form>
<ol id="tasks"></ol>
Solution 2:[2]
On the first event listener you can check for dark mode already on the body tag
form.addEventListener(`submit`, (e) => {
e.preventDefault();
const task = input.value;
const createTaskEl = () => {
const taskEl = document.createElement(`div`);
taskEl.classList.add(`task`);
const taskContentEl = document.createElement(`div`);
taskContentEl.appendChild(document.createTextNode(task));
taskEl.appendChild(taskContentEl);
container.appendChild(taskEl);
input.value = ``;
}
if (!task) {
window.alert(`please fill the input!`);
} else {
// Check if the body element is already in in dark mode
if(!body.classList.contains('bodyDark')){
createTaskEl()
} else {
createTaskEl()
let taskEl = document.querySelector(`.task`);
taskEl.classList.add(`inputDark`);
}
}
});
You needed to check that taskEl exists first.
function darkMode() {
let darkBtn = document.querySelector(`.btn`);
darkBtn.onclick = () => {
let taskEl = document.querySelector(`.task`);
const primaryEls = () => {
form.classList.toggle(`formDark`),
input.classList.toggle(`inputDark`),
body.classList.toggle(`bodyDark`)
}
if(taskEl){
primaryEls();
taskEl.classList.toggle(`inputDark`);
} else {
primaryEls();
}
};
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |