Розгортання контейнерів з посиланнями
Тут показано, як у шапці цієї сторінки працюють елементи, які розгортають додаткові контейнери з посиланнями.
Наприклад, кнопка "фрукти" при кліку лівою кнопкою миші або при активації за допомогою клавіші Enter розгортає контейнер з посиланнями "апельсини", "мандарини", "лимони".
При розгортанні/згортанні в цих кнопок змінюється значення атрибуту aria-expanded ("true" або "false", залежно від стану). Завдяки цьому скрінрідер озвучує відповідні стани при активації елемента: "розгорнуто", "згорнуто".
Завдяки тому, що ці контейнері розташовані в DOM-дереві сторінки одразу за відповідними кнопками, перехід до їхніх посилань здійснюється одразу при першому ж натисканні клавіші Tab.
За потреби, замість <button>...</button> з підлаштованим зовнішнім виглядом можна використати <a role="button">...</a>.
HTML-код цієї шапки:
<div class="flex_row_sta_cen" id="header" style="height: 90px">
<div style="width: 100%">
<div class="flex_row_sta_cen">
<div class="div_header_link" id="link_to_main">
<a class="header_link" href="../">на головну</a>
</div>
<div class="div_header_link">
<button class="button_expander_as_header_link button_expander_expanded_false" aria-expanded="false" target="flying_container_fruits">фрукти</button>
<div class="div_links_flying_container" id="flying_container_fruits" style="display: none">
<div><a class="header_link header_link_in_flying_container" href="../">апельсини</a></div>
<div><a class="header_link header_link_in_flying_container" href="../">мандарини</a></div>
<div><a class="header_link header_link_in_flying_container" href="../">лимони</a></div>
</div>
</div>
<div class="div_header_link">
<button class="button_expander_as_header_link button_expander_expanded_false" aria-expanded="false" target="flying_container_vegetables">овочі</button>
<div class="div_links_flying_container" id="flying_container_vegetables" style="display: none">
<div><a class="header_link header_link_in_flying_container" href="../">помідори</a></div>
<div><a class="header_link header_link_in_flying_container" href="../">огірки</a></div>
<div><a class="header_link header_link_in_flying_container" href="../">капуста</a></div>
</div>
</div>
<div class="div_header_link">
<a class="header_link" href="../">крупи</a>
</div>
<div class="div_header_link">
<a class="header_link" href="../">випічка</a>
</div>
<div class="div_header_link">
<a class="header_link" href="../">солодощі</a>
</div>
<div class="div_header_link">
<a class="header_link" href="../">напої</a>
</div>
</div>
</div>
</div>
Приклад JS-коду, що керує поведінкою контейнерів:
const buttons = document.getElementsByClassName("button_expander_as_header_link");
Array.from(buttons).forEach(button => {
button.addEventListener("click", () => {
console.log(".button_expander_as_header_link was clicked");
FlyingContainers.trigger(button);
});
});
class FlyingContainers
{
static writeLogs = true;
static hideAll() {
this.log("Method FlyingContainers.hideAll was called");
let buttons = document.querySelectorAll(".button_expander_as_header_link");
buttons.forEach((button) => {
let expanded = button.getAttribute("aria-expanded");
if (expanded == "true") {
FlyingContainers.fold(button);
}
});
}
static trigger(button) {
this.log("Method FlyingContainers.trigger was called");
let expanded = button.getAttribute("aria-expanded");
this.hideAll();
if (expanded == "false") {
this.expand(button);
}
}
static expand(button) {
this.log("Method FlyingContainers.expand was called");
let target = document.getElementById(button.getAttribute("target"));
target.style.display = "block";
button.setAttribute("aria-expanded", "true");
button.classList.add("button_expander_expanded_true");
button.classList.remove("button_expander_expanded_false");
}
static fold(button) {
this.log("Method FlyingContainers.fold was called");
let target = document.getElementById(button.getAttribute("target"));
target.style.display = "none";
button.setAttribute("aria-expanded", "false");
button.classList.add("button_expander_expanded_false");
button.classList.remove("button_expander_expanded_true");
}
static log(text) {
if (this.writeLogs) {
console.log(text);
}
}
}
Приклад CSS-коду, що визначає вигляд представлених вище елементів:
.div_header_link {
margin-right: 32px;
padding: 0px 0px 2px 16px;
position: relative;
}
.header_link {
border-bottom: 2px solid;
border-bottom-color: rgba(240, 240, 240, 0.8);
color: #eee;
font-family: "font_semibold";
font-size: 1.1em;
text-decoration: none;
}
.button_expander_as_header_link {
background: none;
border: none;
border-bottom: 2px solid;
border-bottom-color: rgba(240, 240, 240, 0.8);
color: #eee;
cursor: pointer;
font-family: "font_semibold";
font-size: 1.1em;
padding: 0px 0px 2px 0px;
}
.button_expander_expanded_false::after {
content: " ⯆";
}
.button_expander_expanded_true::after {
content: " ⯅";
}
.div_links_flying_container {
background-color: #555;
padding: 16px 16px 4px 16px;
position: absolute;
}
.div_links_flying_container div {
padding: 0px 0px 12px 0px;
}