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

使用GSAP实现悬停下拉列表动画时出现抖动问题的咨询

解决GSAP下拉列表悬停抖动问题

抖动的核心原因是动画过程中容器位置(y值)变化导致鼠标意外触发mouseleave事件,加上固定height与maxHeight的冲突,引发动画反复触发。以下是两种基于GSAP的修复方案:

方案一:固定容器位置,仅动画列表内容

这种方式避免移动整个下拉容器,只让隐藏的列表部分滑入,彻底消除鼠标位置偏移的问题:

修改后的代码

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<div class="languages-dropdown">
  <p class="title">Języki programowania</p>
  <div class="language-list">
    <br>
    <a href="subpages/sub-page0.html" class="language">Javascript</a>
    <a href="subpages/sub-page1.html" class="language">B</a>
    <a href="subpages/sub-page2.html" class="language">C</a>
    <a href="subpages/sub-page3.html" class="language">C++</a>
    <a href="subpages/sub-page4.html" class="language">C#</a>
    <a href="subpages/sub-page5.html" class="language">Rust</a>
    <a href="subpages/sub-page6.html" class="language">Java</a>
    <a href="subpages/sub-page7.html" class="language">Python</a>
    <a href="subpages/sub-page8.html" class="language">Golang</a>
    <a href="subpages/sub-page9.html" class="language">PHP</a>
  </div>
</div>

CSS

.languages-dropdown {
  position: absolute;
  padding: 17px;
  border: none;
  border-radius: 10px;
  background-color: rgb(53, 53, 53);
  width: 230px;
  overflow: hidden;
  max-height: 59px; /* 初始仅显示标题的高度 */
}

.title {
  text-align: center;
  font-size: 20px;
  margin: 0; /* 清除默认margin,避免高度计算偏差 */
}

.language-list {
  margin-left: 60px;
}

.language {
  display: block;
  text-decoration: none;
  padding: 5px;
  font-size: 17px;
}

JS

let languagesDropdown = document.querySelector(".languages-dropdown")
let languageList = document.querySelector(".language-list")

// 初始化列表位置,向上隐藏
gsap.set(languageList, { y: -languageList.offsetHeight })

languagesDropdown.addEventListener("mouseenter", () => {
  // 展开容器高度
  gsap.to(languagesDropdown, {
    ease: "power1.inOut",
    duration: 0.2,
    maxHeight: 375,
  });
  // 滑入列表
  gsap.to(languageList, {
    ease: "power1.inOut",
    duration: 0.2,
    y: 0,
  });
});

languagesDropdown.addEventListener("mouseleave", () => {
  // 收缩容器高度
  gsap.to(languagesDropdown, {
    ease: "power1.inOut",
    duration: 0.2,
    maxHeight: 59,
  });
  // 滑出列表
  gsap.to(languageList, {
    ease: "power1.inOut",
    duration: 0.2,
    y: -languageList.offsetHeight,
  });
});

方案二:保留容器移动,禁用动画过程中的事件冲突

如果必须移动容器位置,可通过临时禁用鼠标事件,避免动画过程中误触发mouseleave:

修改后的JS代码

let languagesDropdown = document.querySelector(".languages-dropdown")

gsap.set(languagesDropdown, {
  y: -250
})

languagesDropdown.addEventListener("mouseenter", () => {
  gsap.to(languagesDropdown, {
    ease: "power1.inOut",
    duration: 0.2,
    y: -92,
    maxHeight: "375px",
    pointerEvents: "none", // 动画过程中禁用鼠标事件
    onComplete: () => {
      languagesDropdown.style.pointerEvents = "auto" // 动画结束恢复
    }
  });
});

languagesDropdown.addEventListener("mouseleave", () => {
  gsap.to(languagesDropdown, {
    ease: "power1.inOut",
    duration: 0.2,
    y: -250,
    maxHeight: 59,
    pointerEvents: "none",
    onComplete: () => {
      languagesDropdown.style.pointerEvents = "auto"
    }
  });
});

关键优化说明

  • 方案一从根源解决问题:固定容器位置,仅动画内部列表,避免鼠标因容器移动意外移出触发事件。
  • 方案二通过pointerEvents临时禁用事件,防止动画过程中反复触发enter/leave。
  • 移除CSS中固定的height值,让maxHeight基于实际内容计算,避免动画结束后高度异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:44:53