You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SlideDown Toggle切换异常:先开新内容后关旧内容问题求助

解决SlideDown内容切换时先展开新内容再关闭旧内容的问题

问题核心原因

当前代码中,调用hideAllContents()移除旧内容的show-content类后,立刻就给新内容添加show-content类。由于CSS过渡动画是异步执行的,旧内容的关闭动画还未完成,新内容的展开动画就已经启动,导致视觉上出现新内容先展开、旧内容后关闭的现象。


具体解决方案

1. 优化DOM结构与类名(消除冗余逻辑)

给所有下拉内容添加通用类slide-down-panel,同时给封面元素添加data-target属性关联对应内容的ID,避免重复编写多个toggleSlideDownN函数:

<div><img src="image/sonstiges.webp" class="SGP" alt="Gemuese"></div>
<div class="coverflow1" data-coverflow="1">
    <div class="cover1" style="background-image: url('image/.webp');" data-target="#slide-content-1"></div>
    <div class="cover1" style="background-image: url('image/.webp');" data-target="#slide-content-2"></div>
    <!-- 其余封面元素按此格式修改 -->
</div>
<div class="slide-down-panel slide-down-content" id="slide-content-1">
    <div id="tableDiv">
        <table>
            <tr>
                <td class="tbName1">Name:</td>
                <td class="tbOrt1">Ort:</td>
                <td class="tbDis1">Entfernung</td>
            </tr>
        </table>
    </div>
</div>
<div class="slide-down-panel slide-down-content1" id="slide-content-2">
    <!-- 对应内容 -->
</div>

2. 统一CSS过渡逻辑

给通用类slide-down-panel设置过渡规则,无需为每个内容单独编写样式:

.coverflow1 {
    display: flex;
    justify-content: left;
    align-items: left;
    height: 100px;
    perspective: 100%;
    scroll-behavior: smooth;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    background-image: url(../image/brett1.webp); 
    background-repeat: no-repeat; 
    background-position: 3px 68px;
    background-size: 98%;
    margin-bottom:5px;
}  

.cover1 {
    flex: 0 0 25%;
    height: 100px;
    margin: 0 4%;
    background-size: 100%, 100%;
    background-repeat: no-repeat;
    background-position: center;
    transform-style: preserve-3d;
    transition: transform 0.5s;
    scroll-snap-align: center;
    scroll-margin-left: 10px;
}

.active {
    transform: scale(1.2) translateZ(0px);
}

.slide-down-panel {
    max-height: 0;
    overflow: hidden;
    transition: max-height 1s ease;
}
.slide-down-panel.show-content {
    max-height: 1000px; /* 设置足够大的值以容纳所有内容 */
}

3. 重构JS逻辑,等待旧内容关闭后再展开新内容

通过监听CSS过渡结束事件,确保旧内容完全关闭后再启动新内容的展开动画:

const covers = document.querySelectorAll('.cover1');
const allPanels = document.querySelectorAll('.slide-down-panel');

// 绑定所有封面点击事件
covers.forEach(cover => {
    cover.addEventListener('click', handleCoverClick);
});

function handleCoverClick(e) {
    const targetPanelId = e.currentTarget.dataset.target;
    const targetPanel = document.querySelector(targetPanelId);
    const activePanel = document.querySelector('.slide-down-panel.show-content');

    // 点击当前激活的封面,切换折叠/展开状态
    if (activePanel === targetPanel) {
        togglePanel(targetPanel, e.currentTarget);
        return;
    }

    // 先关闭所有面板,等待过渡结束后再打开新面板
    closeAllPanels().then(() => {
        covers.forEach(c => c.classList.remove('active'));
        e.currentTarget.classList.add('active');
        targetPanel.classList.add('show-content');
    });
}

// 关闭所有面板,返回Promise等待过渡完成
function closeAllPanels() {
    return new Promise(resolve => {
        let transitionCount = 0;
        const totalPanels = allPanels.length;

        if (totalPanels === 0) {
            resolve();
            return;
        }

        allPanels.forEach(panel => {
            if (panel.classList.contains('show-content')) {
                panel.classList.remove('show-content');
                panel.addEventListener('transitionend', function onTransitionEnd() {
                    transitionCount++;
                    panel.removeEventListener('transitionend', onTransitionEnd);
                    if (transitionCount === totalPanels) resolve();
                }, { once: true });
            } else {
                transitionCount++;
                if (transitionCount === totalPanels) resolve();
            }
        });
    });
}

// 单个面板切换逻辑
function togglePanel(panel, cover) {
    panel.classList.toggle('show-content');
    cover.classList.toggle('active');
}

额外优化说明

  • 移除了原代码中冗余的setAsActive和多个toggleSlideDownN函数,简化逻辑层级
  • 分离封面激活状态与内容展开逻辑,避免类操作冲突
  • 使用Promise封装过渡等待逻辑,确保动画执行顺序符合预期

内容的提问来源于stack exchange,提问作者Ricky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:40:55