#javascript #css #arrays #foreach
Вопрос:
Привет 🙂 Я кодирую переключатель темного режима и столкнулся с проблемой, которую не могу понять.
Я перебираю массив, содержащий элементы, которые выглядят следующим образом: { className: 'h3dark', elementId: 'h2'}
. Затем я использую цикл forEach для применения каждого класса ко ВСЕМ элементам с определенным идентификатором. К сожалению, он применяет каждый класс только к первому html-элементу с идентификатором. Вы знаете, как это можно исправить?
HTML
<h1 id="h1" class="h1">COLOR</h1> <!--Color changed-->
<h1 id="h2" class="h1">COLOR</h1> <!--Color changed-->
<h1 id="h3" class="h1">COLOR</h1> <!--Color changed-->
<h1 id="h1" class="h1">COLOR</h1> <!--Color not changed-->
<h1 id="h2" class="h1">COLOR</h1> <!--Color not changed-->
<h1 id="h3" class="h1">COLOR</h1> <!--Color not changed-->
<button onclick="darkSwitch()">CHANGE COLOR</button>
</div>
язык JavaScript
// checking if cookie exists
var cookieState = Cookies.get('darkMode');
// First visit - cookieState is undefined
// If cookie exists we are parsing it to get a boolean
if(cookieState === undefined){
var isDarkmodeEnabled = false;
}else{
var isDarkmodeEnabled = JSON.parse(cookieState)
};
// Cookie doesn't exist: darkMode = false
// Cookie exists: darkMode = true/false
var darkMode = isDarkmodeEnabled;
// Add dark mode classes and elements' ids
// className - a name of a class with dark mode attributes
// elementId - an id of an element a class will be added to
var darkClasses = [
{ className: 'h1dark', elementId: 'h1'},
{ className: 'h2dark', elementId: 'h3'},
{ className: 'h3dark', elementId: 'h2'},
];
// Adding classes on page load if darkmode is enabled
window.onload = addClassesOnLoad();
// Changing darkMode state and adding or removing classes
function darkSwitch(){
// Setting darkMode to its opposite value
darkMode = !darkMode;
if(darkMode === true){
// Looping through an array and deleting classes
darkClasses.forEach(item => {
document.getElementById(item.elementId).classList.add(item.className)
});
}
else{
// Looping through an array and deleting classes
darkClasses.forEach(item => {
document.getElementById(item.elementId).classList.remove(item.className)
});
};
// Saving darkMode state to the cookie
Cookies.set('darkMode', darkMode);
}
// Adding classes on page load if darkmode is enabled
function addClassesOnLoad(){
if(darkMode === true){
darkClasses.forEach(item =>{
document.getElementById(item.elementId).classList.add(item.className)
});
};
}
Комментарии:
1. НЕ ИСПОЛЬЗУЙТЕ ИДЕНТИФИКАТОРЫ ПОВТОРНО! Это плохая практика. Используйте классы или атрибуты, если вам нужно что-то многоразовое. Обратите внимание, как метод называется document.get Элемент по идентификатору. Не получить элементы по идентификатору. Предполагается, что он возвращает только один элемент.
2. Как вы думаете, это может быть как-то связано с тем, что идентификаторы same…in та половина, которая не работает? Это было бы моей первой подсказкой, если бы я устранял неполадки.
3. атрибут id уникален на странице, поэтому неверно в HTML иметь два дива с одинаковым идентификатором!
Ответ №1:
Попробуйте, как в следующем фрагменте:
/*const cookieState = Cookies.get('darkMode');
if(cookieState === undefined){
let isDarkmodeEnabled = false;
}else{
let isDarkmodeEnabled = JSON.parse(cookieState)
};
let darkMode = isDarkmodeEnabled;*/
let darkMode = true //replace with isDarkmodeEnabled
const darkClasses = [
{ className: 'h1dark', classId: 'h1'},
{ className: 'h2dark', classId: 'h2'},
{ className: 'h3dark', classId: 'h3'},
];
toggleDarkMode()
function darkSwitch(){
darkMode = !darkMode;
toggleDarkMode()
//Cookies.set('darkMode', darkMode);
}
function toggleDarkMode(){
darkClasses.forEach(item => {
const h1s = document.querySelectorAll(`.${item.classId}`)
h1s.forEach(h => h.classList.toggle(item.className))
})
}
.h1dark {
color: orange;
}
.h2dark {
color: red;
}
.h3dark {
color: violet;
}
<h1 id="1" class="h1">COLOR</h1>
<h1 id="2" class="h2">COLOR</h1>
<h1 id="3" class="h3">COLOR</h1>
<h1 id="4" class="h1">COLOR</h1>
<h1 id="5" class="h2">COLOR</h1>
<h1 id="6" class="h3">COLOR</h1>
<button onclick="darkSwitch()">CHANGE COLOR</button>
Комментарии:
1. Спасибо за ваш ответ! Это не сработало, но я внес небольшие изменения, и теперь это работает. Может быть, я неправильно реализовал ваш код.
2. Я не знаю почему, я кодирую уже несколько дней и не могу по-настоящему анализировать код, но я опубликовал решение ниже 🙂
3. Хороший приятель, я рад, что ты нашел решение. Если вам нужна какая-либо помощь, я готов помочь, если смогу. ура 🙂
4.
item.defaultClass
является элементом из вашего массиваdarkClasses
и.
является знаком для класса css (например.h1
). Поэтому, когда вы получили элемент из массива, предположим,item.defaultClass=h1
мы добавим.
его, чтобы мы могли ссылаться на класс css.h1
5. Вы можете узнать больше здесь
Ответ №2:
Благодаря ответу Николы Павичевича я все понял.
darkClasses.forEach(item => {
document.getElementById(item.elementId).classList.add(item.className)
});
Изменено на:
darkClasses.forEach(item => {
var element = document.querySelectorAll(`.${item.defaultClass}`)
element.forEach(h => h.classList.add(item.newDarkClass))
});
и
var darkClasses = [
{ newDarkClass: 'h1dark', defaultClass: 'h1'},
{ newDarkClass: 'h2dark', defaultClass: 'h2'},
{ newDarkClass: 'h3dark', defaultClass: 'h3'},
];
<h1 class="h1">COLOR</h1> <!--Color changed-->
<h1 class="h2">COLOR</h1> <!--Color changed-->
<h1 class="h3">COLOR</h1> <!--Color changed-->
<h1 class="h1">COLOR</h1> <!--Color changed-->
<h1 class="h2">COLOR</h1> <!--Color changed-->
<h1 class="h3">COLOR</h1> <!--Color changed-->