我的JavaScript手风琴没有正确切换。当我点击其标题面板时,我需要隐藏内容

问题描述 投票:0回答:1

我创建了一个创建手风琴的Java Script代码。它现在的工作方式是当你点击一个封闭的内容标题面板时,内容会显示,但当我点击打开的内容的标题面板时,它不会关闭它。因此它打开其他面板但无法关闭当前打开的内容。

我尝试了其他不同的语句,针对不同的Java Script元素,但都引出了相同的结果。

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>
javascript accordion
1个回答
0
投票

问题是e.target不是你想象的那样。 e.target是用户点击的,所以如果他们点击标题或SVG,那么e.target是标题或SVG,而不是你期望的标题行,所以比较:

content.previousElementSibling === e.target 

工作非常不一致。

为了解决这个问题,我编写了以下函数,它将向后搜索包含类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的完整示例,其中包含我从您的sharepoint.stackexchange帖子获得的HTML。它当然没有你所有的风格,但手风琴是有效的。

© www.soinside.com 2019 - 2024. All rights reserved.