#javascript #html #css #bootstrap-4
#javascript #HTML #css #bootstrap-4
Вопрос:
Я пытаюсь написать такую функцию, чтобы при нажатии на вкладку (созданную с помощью bootstrap) она меняла цвет на золотой. Этот бит работает нормально, однако я хочу переключить активное свойство каждой вкладки (bootstrap), чтобы оно было включено для создания красивого белого контура. Проблема в том, что если вы снова не нажмете на ту же вкладку, она останется белой. Есть идеи? Спасибо.
Это моя работа до сих пор:
let timesClicked = 1;
let navItems = document.querySelectorAll('.changeColor');
navItems.forEach(item => {
item.addEventListener("click", () => {
timesClicked ;
console.log(timesClicked);
let previousItem = item;
if (timesClicked % 2 == 0) {
item.style.color = "#f0a500";
item.classList.toggle('active');
console.log(item);
} else {
previousItem.classList.toggle('active');
console.log(previousItem);
};
navItems.forEach(otherItem => {
if (otherItem !== item) {
otherItem.style.color = "#1A1C20";
/*
item.addEventListener("click", () =>
item.classList.toggle('active'));
;*/
};
});
});
})
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab"
aria-controls="Mathematics" aria-selected="true">Mathematics</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab"
aria-controls="profile" aria-selected="false">English</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab"
aria-controls="contact" aria-selected="false">Verbal</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab"
aria-controls="contact" aria-selected="false">Nonverbal</a>
</li>
</ul>
Ответ №1:
Основываясь на вашем коде, я выполнил следующие шаги, чтобы исправить это:
- перед щелчком установите первую вкладку активной по умолчанию.
- при нажатии на любую вкладку отключите предыдущую вкладку и запомните эту активную по переменной
previousItem
(вы должны объявить эту переменную вне forEach(..)).
let navItems = document.querySelectorAll('.changeColor');
let previousItem = navItems[0];
navItems.forEach(item => {
item.addEventListener("click", () => {
if(previousItem == item)return;
item.style.color = "#f0a500";
item.classList.toggle('active');
previousItem.classList.toggle('active');
previousItem.style.color = "#1A1C20";
previousItem = item;
});
})
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab"
aria-controls="Mathematics" aria-selected="true" style="color:#f0a500;">Mathematics</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab"
aria-controls="profile" aria-selected="false">English</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab"
aria-controls="contact" aria-selected="false">Verbal</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab"
aria-controls="contact" aria-selected="false">Nonverbal</a>
</li>
</ul>
Комментарии:
1. Спасибо! как вы добавили оператор return to if в одну строку? Т.е. какова логика?
2. это слишком сложно и требует дополнительных строк кода для достижения этого простого переключения меню. Смотрите мой ответ. Также, пожалуйста, добавьте подробности в свой ответ для других читателей.
3. @github292929 это короткий способ написания оператора if
if(previousItem == item){return;}
, когда у вас есть только одна строка в фигурной скобке, вы можете обойтись без фигурной скобки.4. @AlwaysHelping спасибо за напоминание, я только что добавил детали, и это не слишком сложно, вы можете видеть, что я сохранил
console.logs and timesClicked
, поэтому OP может видеть разницу, ваш ответ отличный! но нужно ли повторять все вкладки каждый раз, когда вы нажимаете?5. @QiuZhou спасибо. Я не думаю, что это излишне, и при этом нет проблем с производительностью, поскольку цель состоит в том, чтобы писать МЕНЬШЕ кода, но всегда достигать одинаковых результатов.
Ответ №2:
Вы слишком усложняете code
, это можно просто сделать, используя querySelectorAll
forEach
метод and .
Просто удалите active
класс и color
из всех nav items
, а затем добавьте только в clicked
пункт меню, используя только метод Event.target
Упрощенная демонстрация кода:
let navItems = document.querySelectorAll('.changeColor');
navItems.forEach(item => {
item.addEventListener("click", (e) => {
navItems.forEach(otherItem => {
otherItem.style.color = "#1A1C20";
otherItem.classList.remove('active');
});
e.target.classList.add('active');
e.target.style.color = "#f0a500";
});
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab" aria-controls="Mathematics" aria-selected="true">Mathematics</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">English</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Verbal</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Nonverbal</a>
</li>
</ul>
Комментарии:
1. спасибо за это, но зачем вам это делать: e.target.classList.remove(‘active’); . Разве это не просто удаляет активный переключатель при каждом нажатии на вкладку?
2. @github292929 нет проблем 🙂
e.target
гарантирует, что мы добавим только к выбранному элементу. и извините, что опечатка. это должно бытьe.target.classList.add('active');
add, а не remove.3. Теперь это имеет большой смысл, мне просто интересно, когда будет указан otherItem? В моем коде другие элементы определяются как те != item — просто запутался в этом бите. Спасибо, и я приму ваш ответ.
4. @github292929 конечно, позвольте мне уточнить.
Otheritem
происходит изforEach
цикла, который находится внутриclick
функции. Он запускается только тогда, когда мы нажимаем на вкладку, он удаляет все цвета и активные классы для каждогоli
элемента, а затемe.target
добавляет цвет и класс только для выбранного элемента.5. извините, позвольте мне уточнить, мне просто интересно, как цикл forEach узнает, что Otheritem отличается от item ? Спасибо
Ответ №3:
Это мое решение вашей проблемы
let navItem = document.querySelectorAll('.changeColor');
function someFunction({ target }) {
navItem.forEach((element) => {
element.style.color = '#1A1C20';
element.classList.remove('active');
});
target.style.color = '#f0a500';
target.classList.toggle('active');
}
navItem.forEach((element) => {
element.addEventListener('click', (e) => someFunction(e));
});