我的 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 那里得到的。它当然没有你所有的风格,但手风琴很管用。