#javascript #html #css
#javascript #HTML #css
Вопрос:
У меня есть проект часто задаваемых вопросов, в котором есть несколько вопросов, на которые можно ответить, когда пользователь нажимает кнопку со стрелкой в каждой строке вопросов. Я использую javascript для изменения элемента css, но он работает только с первой стрелкой, а не с остальными.
Я хочу иметь возможность щелкнуть любую стрелку, чтобы показать каждый ответ. Я подумывал добавить различный идентификатор к каждой стрелке в строке, но это может быть не лучшим подходом.
HTML
<article class="questions">
How many team members can I invite?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow" id="down-arrow">
<hr>
<detail id="answer">
You can invite up to 2 additional users on the Free plan. There is no limit on
team members for the Premium plan.
</detail>
</article>
<article class="questions">
What is the maximum file upload size?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow" id="down-arrow">
<hr>
<detail id="answer">
No more than 2GB. All files in your account must fit your allotted storage space.
</detail>
</article>
<article class="questions">
How do I reset my password?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow" id="down-arrow">
<hr>
<detail id="answer">
Click “Forgot password” from the login page or “Change password” from your profile page.
A reset link will be emailed to you.
</detail>
</article>
<article class="questions">
Can I cancel my subscription?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow" id="down-arrow">
<hr>
<detail id="answer">
Yes! Send us a message and we’ll process your request no questions asked.
</detail>
</article>
<article class="questions">
Do you provide additional support?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow" id="down-arrow">
<hr>
<detail id="answer">
Chat and email support is available 24/7. Phone lines are open during normal business hours.
</detail>
CSS — код
#answer{
display: none;
}
Javascript
document.getElementById('down-arrow').addEventListener("click", toggleAnswers);
const arrow = document.getElementById('down-arrow')
const current = document.getElementById("answer");
function toggleAnswers(){
current.style.display = "inline";
arrow.style.transform = "scaleY(-1)";
}
Комментарии:
1. НЕ используйте повторяющиеся идентификаторы. Как только происходит умножение одного идентификатора, они больше не являются идентификаторами и
document.getElementById('down-arrow')
больше не будут работать должным образом
Ответ №1:
Я бы немного изменил это и переключил класс при нажатии на вопрос, а затем позволил CSS выполнить всю работу.
Обратите внимание, что я полностью удалил идентификаторы, заменив их классами. Элементы могут иметь более одного класса.
Я предоставил альтернативный вариант, если вы хотите придерживаться простого нажатия на стрелку.
//Get the questions
let questions = document.querySelectorAll(".questions");
for (var i = 0; i < questions.length; i ) {
questions[i].addEventListener("click", function(event) {
//Toggle active class when clicked
this.classList.toggle("active");
});
}
/*If you want to only toggle on clicking the arrow use the following loop instead*/
/*for(var i = 0; i < questions.length; i ) {
questions[i].addEventListener("click", function(event){
//Only toggle if arrow clicked
if(event.target.matches(".arrow")){
//Toggle active class when clicked
this.classList.toggle("active");
}
});
}*/
.answer {
display: none;
}
/*Display answer when active*/
.questions.active .answer {
display: initial;
}
/*Change arrow when active*/
.questions.active .arrow {
transform: scale(-1);
}
<article class="questions">
How many team members can I invite?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow">
<hr>
<detail class="answer display">
You can invite up to 2 additional users on the Free plan. There is no limit on team members for the Premium plan.
</detail>
</article>
<article class="questions">
What is the maximum file upload size?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow">
<hr>
<detail class="answer">
No more than 2GB. All files in your account must fit your allotted storage space.
</detail>
</article>
<article class="questions">
How do I reset my password?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow">
<hr>
<detail class="answer">
Click “Forgot password” from the login page or “Change password” from your profile page. A reset link will be emailed to you.
</detail>
</article>
<article class="questions">
Can I cancel my subscription?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow">
<hr>
<detail class="answer">
Yes! Send us a message and we’ll process your request no questions asked.
</detail>
</article>
<article class="questions">
Do you provide additional support?
<img src="images/icon-arrow-down.svg" alt="arrow" class="arrow">
<hr>
<detail class="answer">
Chat and email support is available 24/7. Phone lines are open during normal business hours.
</detail>
</article>
Ответ №2:
- Идентификатор должен быть уникальным. Вы не можете использовать идентификатор несколько раз в HTML-файле, что означает
.getElementById()
, что извлекается только один элемент, который включает его дочерние / внучатые элементы. - Вы должны извлечь несколько элементов, используя
.querySelectorAll()
вместо.getElementById()
. - Вы не можете применить
.addEventListener()
к нескольким элементам (в данном случае технически называемым списком узлов). Вам нужно применить его один за другим, используя.forEach()
Вот один из примеров:
// Get all of the arrows
const arrows = document.querySelectorAll('#faq-container .faq-question__arrow');
// Apply .addEventListener() to each arrow one by one
arrows.forEach(arrow => arrow.addEventListener('click', () => {
// Get each arrow's parent's parent element
const faqItem = arrow.closest(".faq-item");
faqItem.classList.toggle('active');
}));
.faq-question__arrow {
display: inline-block;
cursor: pointer;
}
.faq-answer {
display: none;
}
.faq-item.active .faq-question__arrow {
transform: scaleY(-1)
}
.faq-item.active .faq-answer {
display: initial;
}
<dl id="faq-container">
<div class="faq-item">
<dt class="faq-question">
How old are you?
<span class="faq-question__arrow">🔻</span>
</dt>
<dd class="faq-answer">I'm 20 years old.</dd>
</div>
<div class="faq-item">
<dt class="faq-question">
How are you?
<span class="faq-question__arrow">🔻</span>
</dt>
<dd class="faq-answer">I'm ok.</dd>
</div>
<div class="faq-item">
<dt class="faq-question">
What's your name?
<span class="faq-question__arrow">🔻</span>
</dt>
<dd class="faq-answer">I don't know</dd>
</div>
</dl>