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

如何在父元素导航栏过渡动画结束后再渲染子搜索组件?

问题根源

点击展开按钮时你同步执行了两个操作:给导航栏添加expanded类触发1000ms的高度过渡、同时将isExpanded设为true直接渲染搜索框组件,二者执行时序不一致导致搜索框提前显示。

方案1:纯CSS实现(推荐)

无需修改核心JS逻辑,性能稳定无计时偏差,仅需调整两处代码:

  1. 移除JSX中对expandedContainer的条件渲染,改为永久渲染:
// 把原来的条件渲染代码替换为下面这段
<div className="expandedContainer">
  <ServiceSearchFields />
</div>
  1. 调整SCSS样式,给搜索框容器加显隐过渡,和导航栏展开时序对齐:
.expandedContainer {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    gap: 15px;
    /* 新增以下4行 */
    opacity: 0;
    visibility: hidden;
    /* 延迟0.8s触发显隐过渡,刚好导航快完成展开时显示搜索框 */
    transition: opacity 0.2s ease 0.8s, visibility 0.2s ease 0.8s;
}
/* 导航展开后显示搜索框容器 */
.navWrapper.expanded .expandedContainer {
    opacity: 1;
    visibility: visible;
}
/* 关闭时搜索框立刻隐藏,无需延迟 */
.navWrapper:not(.expanded) .expandedContainer {
    transition: opacity 0.2s ease, visibility 0.2s ease;
}

方案2:JS定时器控制渲染时序

如果你需要保留条件渲染的逻辑,可以用定时器和导航过渡时长对齐,修改JS代码如下:

import { useState, useRef, useEffect } from 'react';

const NavMobile = () => {
  const [isExpanded, setIsExpanded] = useState(false);
  const timerRef = useRef(null);

  const expandNav = () => {
    document.getElementById("nav")?.classList.add("expanded");
    // 延迟1000ms(和过渡时长一致)再渲染搜索框
    timerRef.current = setTimeout(() => {
      setIsExpanded(true);
    }, 1000);
  };

  const closeNav = () => {
    // 先隐藏搜索框
    setIsExpanded(false);
    // 延迟1000ms再收起导航
    timerRef.current = setTimeout(() => {
      document.getElementById("nav")?.classList.remove("expanded");
    }, 1000);
  };

  // 组件卸载时清除定时器,避免内存泄漏
  useEffect(() => {
    return () => clearTimeout(timerRef.current);
  }, []);

  return (
    <div id="nav" className="navWrapper">
      <nav className="container">
        <button
          className="navButton"
          style={{ display: isExpanded ? "none" : undefined }}
          onClick={expandNav}
        >
          <i className="fa fa-search"></i> Search a service ...
        </button>
        {isExpanded ? (
          <div className="expandedContainer">
            <ServiceSearchFields />
          </div>
        ) : null}
      </nav>
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:54:10