Как реализовать действие "открытия" аккордеона для innerHTML?
Реализация html-accordion выглядит так:
let acc = document.getElementsByClassName("accordion");
for (let i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
let panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
<div class="accordionPaper">
<div>
<button class="accordion">Section Demo</button>
<div class="panel">
<p>Hello, my name Tragislav</p>
<button>Delete</button>
</div>
</div>
</div>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.active,
.accordion:hover {
background-color: #ccc;
}
.panel {
padding: 0 18px;
background-color: white;
display: block;
overflow: hidden;
}
Но если я хочу создавать аккордеоны через
function addPaper(title, authors) {
const element = document.createElement("div");
element.innerHTML = `
<button class="accordion">${title}</button>
<div class="panel">
<p>Authors: ${authors}</p>
<button>Delete</button>
</div>
`;
document.querySelector(".accordionPaper").append(element);
}
Как мне реализовать "открытие" аккордеона для этой функции?
Ответы (1 шт):
Автор решения: OPTIMUS PRIME
→ Ссылка
Добавить обработчик события не на элементы, а на их общего родителя. А при клике проверять, на кого кликнули. Если это искомый элемент - запустить функцию. Называется «Делегирование событий»
let paper = document.querySelector(".accordionPaper");
paper.addEventListener("click", function(e) {
let accordion = e.target.closest(".accordion");
if (!accordion) return; // Клик был не внутри аккордеона? Прервать функцию.
let panel = accordion.nextElementSibling;
let isVisible = (panel.style.display || getComputedStyle(panel).display) != "none";
panel.style.display = isVisible ? "none" : "block";
});
/***/
addPaper(2, 222);
addPaper(3, 333);
function addPaper(title, authors) {
const element = document.createElement("div");
element.innerHTML = (`
<button class="accordion">${ title }</button>
<div class="panel">
<p>Authors: ${ authors }</p>
<button>Delete</button>
</div>
`);
paper.append(element);
}
.accordion {
width: 100%;
padding: 18px;
margin: 2px 0;
border: none;
outline: none;
text-align: left;
transition: 0.4s;
background-color: #eee;
color: #444;
cursor: pointer;
}
.accordion:hover {
background-color: #ccc;
}
.panel {
display: none;
padding: 0 18px;
background-color: white;
overflow: hidden;
}
<div class="accordionPaper">
<div>
<button class="accordion">Bubu</button>
<div class="panel">
<p>Bubu</p>
<button>Delete</button>
</div>
</div>
</div>
is_visible = (panel.style.display || getComputedStyle(panel).display) != "none"; — Если display определен в CSS, но не в HTML, panel.style.display вернет пустую строку (в логическом контексте — false), тогда сработает вторая часть выражения, которая даст реальное значение display.