我的 JavaScript 手风琴未正确切换。当我点击它的标题面板时,我需要隐藏内容
My JavaScript accordion is not toggling properly. I need the content to hide when I click on its title panel
我创建了一个 Java 脚本代码来创建手风琴。它现在的工作方式是,当您单击关闭的内容标题面板时,内容将显示,但是当我单击打开内容的标题面板时,它不会关闭它。所以它打开了其他面板,但无法关闭当前打开的内容。
我尝试了针对不同 Java 脚本元素的不同 else is 语句,但所有这些都导致我得到相同的结果。
function addClass(el, klass) {
el.classList.add(klass);
}
function removeClass(el, klass) {
el.classList.remove(klass);
}
const accordionItems = document.querySelectorAll(".accordion-item");
const accordionContentPanes = document.querySelectorAll(".accordion-content");
// Hide each besides target accordion on click
accordionItems.forEach(function(accordion) {
// Clicked accordions clickable target
const accordionTitleRow = accordion.firstElementChild;
console.log(accordion);
accordionTitleRow.addEventListener("click", toggleAccordion);
});
function toggleAccordion(e) {
accordionContentPanes.forEach(function(content) {
console.log(content);
// Check if clicked row matches the content's previous element sibling
if (content.previousElementSibling === e.target) {
removeClass(content, "hidden");
addClass(content.parentElement, "active");
}
else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
});
}
最终结果是我已经拥有的加上我上面解释的功能。
HTML 看起来像:
<div class="accordion-item overflow-hidden w-full">
<div style="border-bottom: 1px solid #e2e2e2; border-top: 1px solid #e2e2e2;;" class="accordion-title-row flex justify-between items-center cursor-pointer
px-6 py-4 headerItem" id="first">
<div class="flex">
<i style=" font-size: 1.75em;margin-right: .5em;" class="fas fa-car fa-3x grey-text overlay"></i>
<h2 style="padding-top: .15em;" class="font-bold text-lg mb-0">Automotive</h2>
</div>
<div>
<svg style="color: #2196f3;" viewBox="0 0 20 20" width="20" height="20" class="fill-current text-grey-dark accordion-arrow">
<title>cheveron down</title>
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
</svg>
</div>
</div>
<div id="automotive" class="accordion-content list-reset leading-normal px-8 py-4 hidden">
Here is some content
</div>
</div>
<div class="accordion-item overflow-hidden w-full">
<div style="border-bottom: 1px solid #e2e2e2; border-top: 1px solid #e2e2e2;;" class="accordion-title-row flex justify-between items-center cursor-pointer
px-6 py-4 headerItem" id="second">
<div class="flex">
<i style=" font-size: 1.75em;margin-right: .5em;" class="fas fa-car fa-3x grey-text overlay"></i>
<h2 style="padding-top: .15em;" class="font-bold text-lg mb-0">Other</h2>
</div>
<div>
<svg style="color: #2196f3;" viewBox="0 0 20 20" width="20" height="20" class="fill-current text-grey-dark accordion-arrow">
<title>cheveron down</title>
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
</svg>
</div>
</div>
<div id="other" class="accordion-content list-reset leading-normal px-8 py-4 hidden">
Here is some more content
</div>
</div>
问题是 e.target
不是你想的那样。 e.target
是用户点击的内容,因此如果他们点击 header 或 SVG,则 e.target 是 header 或 SVG,而不是标题行很期待,所以比较:
content.previousElementSibling === e.target
工作非常不一致。
为了修复它,我编写了以下函数,它将向后搜索包含 class accordion-title-row
.
的 parent
function getTitleRowFromChild(elem) {
var result = elem;
while(result && !result.classList.contains("accordion-title-row")) {
if(result.parentElement)
result = result.parentElement;
}
return result;
}
然后我像这样修改了 toggleAccordion:
function toggleAccordion(e) {
// get the title row from the target
var titleRow = getTitleRowFromChild(e.target);
accordionContentPanes.forEach(function(content) {
// change comparison to title row instead of e.target
if (content.previousElementSibling === titleRow) {
// this block is the only change
if(content.classList.contains("hidden")) {
removeClass(content, "hidden");
addClass(content.parentElement, "active");
}
else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
} else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
});
}
之后手风琴按预期工作。 jsfiddle 上的完整示例,其中包括 HTML 我从您的 sharepoint.stackexchange post 那里得到的。它当然没有你所有的风格,但手风琴很管用。
我创建了一个 Java 脚本代码来创建手风琴。它现在的工作方式是,当您单击关闭的内容标题面板时,内容将显示,但是当我单击打开内容的标题面板时,它不会关闭它。所以它打开了其他面板,但无法关闭当前打开的内容。
我尝试了针对不同 Java 脚本元素的不同 else is 语句,但所有这些都导致我得到相同的结果。
function addClass(el, klass) {
el.classList.add(klass);
}
function removeClass(el, klass) {
el.classList.remove(klass);
}
const accordionItems = document.querySelectorAll(".accordion-item");
const accordionContentPanes = document.querySelectorAll(".accordion-content");
// Hide each besides target accordion on click
accordionItems.forEach(function(accordion) {
// Clicked accordions clickable target
const accordionTitleRow = accordion.firstElementChild;
console.log(accordion);
accordionTitleRow.addEventListener("click", toggleAccordion);
});
function toggleAccordion(e) {
accordionContentPanes.forEach(function(content) {
console.log(content);
// Check if clicked row matches the content's previous element sibling
if (content.previousElementSibling === e.target) {
removeClass(content, "hidden");
addClass(content.parentElement, "active");
}
else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
});
}
最终结果是我已经拥有的加上我上面解释的功能。
HTML 看起来像:
<div class="accordion-item overflow-hidden w-full">
<div style="border-bottom: 1px solid #e2e2e2; border-top: 1px solid #e2e2e2;;" class="accordion-title-row flex justify-between items-center cursor-pointer
px-6 py-4 headerItem" id="first">
<div class="flex">
<i style=" font-size: 1.75em;margin-right: .5em;" class="fas fa-car fa-3x grey-text overlay"></i>
<h2 style="padding-top: .15em;" class="font-bold text-lg mb-0">Automotive</h2>
</div>
<div>
<svg style="color: #2196f3;" viewBox="0 0 20 20" width="20" height="20" class="fill-current text-grey-dark accordion-arrow">
<title>cheveron down</title>
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
</svg>
</div>
</div>
<div id="automotive" class="accordion-content list-reset leading-normal px-8 py-4 hidden">
Here is some content
</div>
</div>
<div class="accordion-item overflow-hidden w-full">
<div style="border-bottom: 1px solid #e2e2e2; border-top: 1px solid #e2e2e2;;" class="accordion-title-row flex justify-between items-center cursor-pointer
px-6 py-4 headerItem" id="second">
<div class="flex">
<i style=" font-size: 1.75em;margin-right: .5em;" class="fas fa-car fa-3x grey-text overlay"></i>
<h2 style="padding-top: .15em;" class="font-bold text-lg mb-0">Other</h2>
</div>
<div>
<svg style="color: #2196f3;" viewBox="0 0 20 20" width="20" height="20" class="fill-current text-grey-dark accordion-arrow">
<title>cheveron down</title>
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
</svg>
</div>
</div>
<div id="other" class="accordion-content list-reset leading-normal px-8 py-4 hidden">
Here is some more content
</div>
</div>
问题是 e.target
不是你想的那样。 e.target
是用户点击的内容,因此如果他们点击 header 或 SVG,则 e.target 是 header 或 SVG,而不是标题行很期待,所以比较:
content.previousElementSibling === e.target
工作非常不一致。
为了修复它,我编写了以下函数,它将向后搜索包含 class accordion-title-row
.
function getTitleRowFromChild(elem) {
var result = elem;
while(result && !result.classList.contains("accordion-title-row")) {
if(result.parentElement)
result = result.parentElement;
}
return result;
}
然后我像这样修改了 toggleAccordion:
function toggleAccordion(e) {
// get the title row from the target
var titleRow = getTitleRowFromChild(e.target);
accordionContentPanes.forEach(function(content) {
// change comparison to title row instead of e.target
if (content.previousElementSibling === titleRow) {
// this block is the only change
if(content.classList.contains("hidden")) {
removeClass(content, "hidden");
addClass(content.parentElement, "active");
}
else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
} else {
removeClass(content.parentElement, "active");
addClass(content, 'hidden');
}
});
}
之后手风琴按预期工作。 jsfiddle 上的完整示例,其中包括 HTML 我从您的 sharepoint.stackexchange post 那里得到的。它当然没有你所有的风格,但手风琴很管用。