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

如何用JavaScript和CSS实现点击切换图片src并完成rotateX翻转效果?

Fixing Your Menu Flip Button Toggle Issue

Hey there, let's break down why your menu flip button is either only working once or failing to transition back properly. I've dealt with similar transition bugs before, so here's the root of the problem and how to fix it.

What's Going Wrong?

  1. Unreliable src check: Browsers automatically convert relative URLs like ./icons/menu.svg to absolute URLs (e.g., http://your-site.com/icons/menu.svg). That means your menu.src === './icons/menu.svg' condition will only be true the first time you click—after that, the check fails, and your toggle logic breaks.
  2. Misordered state changes: Swapping the image src and toggling the flip class in the wrong order can confuse the browser's rendering engine, causing the transition to not fire when switching back to the menu icon.

Solution 1: Fix the Existing Image Swap Logic

We'll replace the src check with an explicit state flag (using a data-state attribute) and adjust the order of operations to ensure the transition fires every time.

Updated JavaScript

const navSlide = () => {
  const menuBtn = document.querySelector("#menu");
  const navItems = document.querySelector(".nav-items");

  menuBtn.addEventListener("click", () => {
    navItems.classList.toggle("open");
    // Check current state using data-state instead of src
    const isMenu = menuBtn.dataset.state === "menu";
    
    // Toggle the flip class first to trigger the transition
    menuBtn.classList.toggle('menu-flip');
    
    // Wait for the transition to finish before swapping the image (smoother result)
    setTimeout(() => {
      if (isMenu) {
        menuBtn.src = './icons/close.svg';
        menuBtn.dataset.state = "close";
      } else {
        menuBtn.src = './icons/menu.svg';
        menuBtn.dataset.state = "menu";
      }
    }, 200); // Match your transition duration (0.2s = 200ms)
  });
};

// Set initial state when the script loads
document.querySelector("#menu").dataset.state = "menu";
navSlide();

Updated CSS

#menu {
  font-family: "Syne Regular", Georgia, "Times New Roman", Times, serif;
  font-size: 54px;
  text-decoration: none;
  color: black;
  position: absolute;
  bottom: 0;
  left: 0;
  margin: 0;
  line-height: 42px;
  letter-spacing: -1px;
  padding: 0;
  border: 0;
  background: none;
  transform: rotateX(0deg);
  transition: transform 0.2s ease-in;
  /* Add backface-visibility to prevent flickering during flip */
  backface-visibility: hidden;
}

#menu.menu-flip {
  transform: rotateX(180deg);
  letter-spacing: -4px;
  /* No need to re-declare transition here—it inherits from the base rule */
}

Updated HTML

<div class="menu">
  <img id="menu" src="./icons/menu.svg" alt="menu" data-state="menu" />
</div>

Solution 2: Smoother Container Flip (No Image Swap)

If you want even more consistent transitions, wrap both icons in a container and flip the container instead of swapping images. This eliminates any issues with image loading or URL path checks entirely.

HTML

<div class="menu-button" id="menu">
  <img src="./icons/menu.svg" alt="menu" class="icon menu-icon" />
  <img src="./icons/close.svg" alt="close" class="icon close-icon" />
</div>

CSS

.menu-button {
  position: absolute;
  bottom: 0;
  left: 0;
  transform: rotateX(0deg);
  transition: transform 0.2s ease-in;
  backface-visibility: hidden;
  /* Fix the container size to prevent layout shifts */
  width: 60px;
  height: 42px;
}

.menu-button.flip {
  transform: rotateX(180deg);
}

.icon {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.close-icon {
  /* Pre-flip the close icon so it faces the right way when the container flips */
  transform: rotateX(180deg);
}

JavaScript

const navSlide = () => {
  const menuBtn = document.querySelector("#menu");
  const navItems = document.querySelector(".nav-items");

  menuBtn.addEventListener("click", () => {
    navItems.classList.toggle("open");
    menuBtn.classList.toggle("flip");
  });
};

navSlide();

Why These Fixes Work

  • data-state flag: Explicitly tracks the button's current state, avoiding the unreliable src path check that breaks after the first click.
  • Transition timing: Waiting for the flip animation to finish before swapping images (in Solution 1) ensures the browser renders the transition smoothly.
  • Container flip (Solution 2): Removes image swapping entirely, making the toggle seamless and consistent every time—no more broken transitions or one-click-only behavior.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:37:43