#javascript
#javascript
Вопрос:
Я пытаюсь получить всех родителей (у которых есть класс «parent») элемента (у которых есть класс «active»), а затем применить к нему стиль. Но, похоже, он не находит те элементы, которые я запрашиваю.
Это HTML-код, который я сейчас использую:
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
И я использую следующий файл Javascript, чтобы применить стиль ко всем родителям с классом «parent» начального элемента с классом «active»:
function openList() {
el = document.getElementsByClassName("active");
while (el.parentNode) {
el = el.parentNode;
if (el.className === "parent") {
el.style.display="block";
}
}
}
window.onload = openList();
Он ничего не возвращает, ни ошибок, но, похоже, работает.
Комментарии:
1.
el.className === "parent"
это проверка, которая завершится неудачей, если этот элемент имеет более одного класса.el.classList
очень полезно для этого…2.
window.onload = openList();
<— неверно3. developer.mozilla.org/en-US/docs/Web/API/Element/closest
4. Возможно, вы захотите
el.parentElement.parentElement
увидеть, как это 2 узла вверх по дереву. Или вы могли бы сделатьel.parentElement.closest("li")
, если родительский элемент находится выше по dom.
Ответ №1:
Есть две проблемы с кодом.
getElementsByClassName
ВозвратHTMLCollection
элемента списка вы должны получить доступ к его первому элементу с помощью[0]
- Вы устанавливаете window.onload для
return
функцииopenList
. Просто не вызывайте функцию, т.е. удалите()
Примечание: вы объявляете el
как глобальную переменную. используйте let
var
или const
для объявления.
function openList() {
let el = document.getElementsByClassName("active")[0];
while (el.parentNode) {
el = el.parentNode;
if (el.className === "parent") {
el.style.display="block";
}
}
}
window.onload = openList;
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
Комментарии:
1. в зависимости от того, насколько велик ваш html, может быть лучшим подходом получить все элементы с классом ‘parent’ и посмотреть, есть ли у них дочерний элемент с классом ‘active’
2. Я не понимаю, как это может быть лучшим подходом, чем этот @jonathanHeindl Также @MaheerAli должен использовать classlist, например
element.classList.contains(class);
Ответ №2:
Сначала вы вызываете функцию и присваиваете то, что она возвращает в
querySelector(), closest() и classList были бы лучшим способом справиться с этим
document.querySelector("li.active")
.closest(".parent")
.classList
.add("open");
li.parent {
display: none;
}
li.parent.open {
display: block;
}
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
Если существует более одного
document.querySelectorAll("li.active").forEach(element =>
element
.closest(".parent")
.classList
.add("open")
)
li.parent {
display: none;
}
li.parent.open {
display: block;
}
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
Ответ №3:
function openList() {
let el = document.getElementsByClassName("parent");
Array.prototype.forEach.call(el,(parentNode)=>{
if(parentNode.getElementsByClassName('active').length>0){
parentNode.style.display="block";
}
});
}
window.onload = openList;
<ul>
<li class="parent">
<ul class="children">
<li class="active">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
Я предлагаю этот подход, поскольку он, вероятно, лучше работает во время выполнения