提问人:Mike Hermary 提问时间:11/2/2023 更新时间:11/4/2023 访问量:37
使用 vanilla JS 切换 HTML 按钮的基于文本的数据属性,而不影响嵌套图标
Toggle text-based data attributes of HTML buttons without affecting nested icons using vanilla JS
问:
我使用以下箭头函数在两个 HTML 按钮上切换属性、类和数据属性。
第一个按钮包含文本,第二个按钮仅包含嵌套的 SVG 图标。
文本交换适用于带有文本的按钮,但在单击时会从按钮中删除嵌套的 SVG 图标。
如何修改功能以保持基于文本的按钮上的文本交换,即使单击另一个按钮并使 SVG 图标保持不变。
window.addEventListener("DOMContentLoaded", function() {
const navigation = (() => {
const buttons = document.querySelectorAll("[data-nav-toggle]");
const containers = document.querySelectorAll("[data-nav-container]");
if (!buttons) return;
function menuToggleHandler() {
buttons.forEach((button) => {
button.addEventListener("click", toggleContainer);
});
}
function toggleContainer(e) {
e.stopPropagation();
toggleButtonAttributes(e.target);
toggleContainers(e.target);
}
function toggleButtonAttributes(button) {
button.classList.toggle("is-active");
const expandedValue = button.getAttribute("aria-expanded");
const setValue = expandedValue === "true" ? "false" : "true";
button.setAttribute("aria-expanded", setValue);
const originalValue = button.getAttribute("data-text-original");
const swapValue = button.getAttribute("data-text-swap");
if (swapValue === button.innerText) {
button.innerText = button.getAttribute("data-text-original");
} else {
button.setAttribute("data-text-original", button.innerText);
button.innerText = button.getAttribute("data-text-swap");
}
document.querySelectorAll(".is-active").forEach(function(buttonActive) {
if (buttonActive !== button) {
buttonActive.classList.remove("is-active");
buttonActive.setAttribute("aria-expanded", false);
if (swapValue === buttonActive.innerText) {
buttonActive.innerText = buttonActive.getAttribute(
"data-text-original"
);
}
}
});
}
function toggleContainers(button) {
const parent = button
.closest("nav")
.querySelector("[data-nav-container]");
parent.classList.toggle("is-expanded");
document
.querySelectorAll(".is-expanded")
.forEach(function(parentExpanded) {
if (parentExpanded !== parent) {
parentExpanded.classList.remove("is-expanded");
}
});
}
menuToggleHandler();
})();
});
button>svg {
pointer-events: none;
}
<nav aria-label="Main navigation">
<button class="c-btn c-btn__menu-toggle" aria-expanded="false" aria-haspopup="menu" data-nav-toggle="global-navigation" data-text-swap="Close" data-text-original="Menu">Menu</button>
<div class="c-navigation" data-nav-container="global-navigation"></div>
</nav>
<nav aria-label="User navigation">
<button class="c-btn c-btn__user-menu-toggle" aria-expanded="false" aria-haspopup="menu" aria-label="User menu toggle" data-nav-toggle="user-navigation">
<svg role="img" width="14" height="16" xmlns="http://www.w3.org/2000/svg" aria-labelledby="user-menu-icon">
<title id="user-menu-icon">
Title
</title>
<path d="M9.5 4a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0zM3 4a4 4 0 1 1 8 0 4 4 0 0 1-8 0zM1.54 14.5h10.92A4.073 4.073 0 0 0 8.427 11H5.572a4.073 4.073 0 0 0-4.031 3.5zM0 15.072A5.57 5.57 0 0 1 5.572 9.5h2.856A5.57 5.57 0 0 1 14 15.072a.928.928 0 0 1-.928.928H.928A.928.928 0 0 1 0 15.072z" fill="#DCD9D6" />
</svg>
</button>
<div class="c-navigation is-expanded" data-nav-container="user-navigation"></div>
</nav>
答:
0赞
Mike Hermary
11/4/2023
#1
我能够通过首先检查按钮元素是否包含纯文本来解决我的问题,方法是将语句放在周围,然后在 buttonActive forEach 函数中创建一个新的 const 并调整文本交换值的 inf 语句。if (button.innerText) {}
if (swapValue === button.innerText) {}
我添加的代码是从活动按钮中检索值,然后在语句中使用该值,使用该属性将活动按钮的 innerText 更改回原始值。const activeSwapValue = buttonActive.getAttribute("data-text-swap");
data-text-swap
if (activeSwapValue === buttonActive.innerText) {}
data-text-original
window.addEventListener("DOMContentLoaded", function() {
const navigation = (() => {
const buttons = document.querySelectorAll("[data-nav-toggle]");
const containers = document.querySelectorAll("[data-nav-container]");
if (!buttons) return;
function menuToggleHandler() {
buttons.forEach((button) => {
button.addEventListener("click", toggleContainer);
});
}
function toggleContainer(e) {
e.stopPropagation();
toggleButtonAttributes(e.target);
toggleContainers(e.target);
}
function toggleButtonAttributes(button) {
button.classList.toggle("is-active");
const expandedValue = button.getAttribute("aria-expanded");
const setValue = expandedValue === "true" ? "false" : "true";
button.setAttribute("aria-expanded", setValue);
const originalValue = button.getAttribute("data-text-original");
const swapValue = button.getAttribute("data-text-swap");
// Added if statement to check if button element contains plain text
if (button.innerText) {
if (swapValue === button.innerText) {
button.innerText = button.getAttribute("data-text-original");
} else {
button.setAttribute("data-text-original", button.innerText);
button.innerText = button.getAttribute("data-text-swap");
}
}
document.querySelectorAll(".is-active").forEach(function(buttonActive) {
// Added const to retrieve data-text-swap attribute from active button
const activeSwapValue = buttonActive.getAttribute("data-text-swap");
if (buttonActive !== button) {
buttonActive.classList.remove("is-active");
buttonActive.setAttribute("aria-expanded", false);
// Changed swapValue to activeSwapValue in the if statement
if (activeSwapValue === buttonActive.innerText) {
buttonActive.innerText = buttonActive.getAttribute(
"data-text-original"
);
}
}
});
}
function toggleContainers(button) {
const parent = button
.closest("nav")
.querySelector("[data-nav-container]");
parent.classList.toggle("is-expanded");
document
.querySelectorAll(".is-expanded")
.forEach(function(parentExpanded) {
if (parentExpanded !== parent) {
parentExpanded.classList.remove("is-expanded");
}
});
}
menuToggleHandler();
})();
});
button>svg {
pointer-events: none;
}
<nav aria-label="Main navigation">
<button class="c-btn c-btn__menu-toggle" aria-expanded="false" aria-haspopup="menu" data-nav-toggle="global-navigation" data-text-swap="Close" data-text-original="Menu">Menu</button>
<div class="c-navigation" data-nav-container="global-navigation"></div>
</nav>
<nav aria-label="User navigation">
<button class="c-btn c-btn__user-menu-toggle" aria-expanded="false" aria-haspopup="menu" aria-label="User menu toggle" data-nav-toggle="user-navigation">
<svg role="img" width="14" height="16" xmlns="http://www.w3.org/2000/svg" aria-labelledby="user-menu-icon">
<title id="user-menu-icon">
Title
</title>
<path d="M9.5 4a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0zM3 4a4 4 0 1 1 8 0 4 4 0 0 1-8 0zM1.54 14.5h10.92A4.073 4.073 0 0 0 8.427 11H5.572a4.073 4.073 0 0 0-4.031 3.5zM0 15.072A5.57 5.57 0 0 1 5.572 9.5h2.856A5.57 5.57 0 0 1 14 15.072a.928.928 0 0 1-.928.928H.928A.928.928 0 0 1 0 15.072z" fill="#DCD9D6" />
</svg>
</button>
<div class="c-navigation is-expanded" data-nav-container="user-navigation"></div>
</nav>
评论