悬停效果被视为点击效果,但在调整页面大小后它们可以正常工作

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

他们之前正在工作,但我试图添加基于反应的页面链接,这似乎破坏了悬停效果,现在我无法让它们再次正常运行。它们在单击时执行正确的悬停动画,并且在我调整页面大小后完美工作。在我调整大小之前,它也不会显示悬停在它们上方的“可点击”鼠标指针以及页面上的另一个按钮。这里有什么问题吗?

编辑:它似乎可以在 Chrome 中的新页面上工作,但不能在打开了许多其他选项卡的选项卡中工作 - 这就是调整大小悬停事件发生时的情况。

我的应用程序页面:

import React from "react";
import Home from "./pages/Home";
import "./Styles/index.css";

const App: React.FC = () => {
 return (
   <div className="app">
     <Home />
   </div>
 );
};

export default App;

我的主页:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./Styles/index.css";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

我的主页:

import React from "react";
import TopBar from "../components/TopBar";
import IntroSection from "../components/IntroSection";
import "../Styles/DefaultPage.css";

const Home: React.FC = () => {
  return (
    <div className="home-screen">
      <TopBar />
      <IntroSection />
    </div>
  );
};

export default Home;

我的顶栏:

import React, { useEffect, useState } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import "../Styles/TopBar.css";

gsap.registerPlugin(ScrollTrigger);

const TopBar: React.FC = () => {
  const [darkMode, setDarkMode] = useState(false);

  useEffect(() => {
    // Add button swing animation
    const navButtons = document.querySelectorAll(".nav-button");
    console.log("useEffect fired - styles should be applied now");
    navButtons.forEach((button) => {
      const btn = button as HTMLElement;

      btn.addEventListener("mouseenter", () => {
        btn.style.animation = "none"; // Remove existing animation
        btn.offsetHeight; // Trigger reflow
        btn.style.animation = "swing 2s ease-in-out forwards"; // Reapply animation
      });
      btn.style.display = "none";
      btn.offsetHeight; // Trigger reflow
      btn.style.display = ""; // Reset display
    });

    return () => {
      navButtons.forEach((button) => {
        const btn = button as HTMLElement;
        btn.removeEventListener("mouseenter", () => {});
      });
    };
  }, []);

  const toggleDarkMode = () => {
    setDarkMode((prevMode) => !prevMode);
    document.body.classList.toggle("dark-mode");
  };

  return (
    <div className="top-bar">
      <div className="nav-buttons">
        <button className="nav-button">HOME</button>
        <button className="nav-button">DEV & DESIGN</button>
        <button className="nav-button">ACTING</button>
        <button className="nav-button">FILMMAKING</button>
      </div>
      <div className="dark-mode-toggle-container">
        <button className="dark-mode-toggle" onClick={toggleDarkMode}>
          {darkMode ? "Light Mode" : "Dark Mode"}
        </button>
      </div>
    </div>
  );
};

export default TopBar;

顶部栏CSS:

.top-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  background-color: white;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Navigation buttons container */
.nav-buttons {
  display: flex;
  padding-left: 20px;
  gap: 20px; /* Space between buttons */
  height: 100%;
  padding-right: 20px;
}

/* Individual navigation button styling */
.nav-button {
  background: none;
  border: none;
  font-family: inherit;
  font-size: 1rem;
  cursor: pointer;
  color: #333;
  padding: 10px;
  transform-origin: top left;
  transition: transform 0.1s ease, color 0.3s ease;
  align-items: center;
}

/* Color change on hover */
.nav-button:hover {
  animation: wiggle 0.5s ease-in-out; /* Use the same animation keyframes */
  color: #555;
}

/* Swing animation class to add animation on hover */
.swing-animation {
  animation: swing 2s ease-in-out forwards;
}

/* Dark mode toggle button styling */
.dark-mode-toggle {
  background: none;
  border: 2px solid #333;
  font-family: inherit;
  font-size: 1rem;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 4px;
  transition: background-color 0.3s ease, color 0.3s ease;
}
.dark-mode-toggle-container {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-right: 20px;
}

.dark-mode-toggle:hover {
  background-color: #333;
  color: #fff;
}

/* Dark mode styles */
body.dark-mode {
  background-color: #333;
  color: #fff;
}

body.dark-mode .top-bar {
  background-color: #000; /* Solid black for dark mode */
}

body.dark-mode .nav-button {
  color: #ccc;
}

body.dark-mode .dark-mode-toggle {
  color: #fff;
}
@keyframes wiggle {
  0% {
    transform: rotate(0deg);
  }
  25% {
    transform: rotate(3deg);
  }
  50% {
    transform: rotate(-3deg);
  }
  75% {
    transform: rotate(2deg);
  }
  100% {
    transform: rotate(0deg);
  }
}
/* Swinging animation */
@keyframes swing {
  0% {
    transform: rotate(0deg);
  }
  10% {
    transform: rotate(15deg);
  }
  20% {
    transform: rotate(-10deg);
  }
  30% {
    transform: rotate(7deg);
  }
  40% {
    transform: rotate(-5deg);
  }
  50% {
    transform: rotate(3deg);
  }
  60% {
    transform: rotate(-2deg);
  }
  70% {
    transform: rotate(1deg);
  }
  80% {
    transform: rotate(-0.5deg);
  }
  90% {
    transform: rotate(0.2deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

我当前的网站测试版本:https://mattekranz.com/

javascript html css animation hover
1个回答
0
投票

这个问题似乎是 React 的渲染怪癖和动画处理的结合。因此,我会尝试组合解决方案:

  1. 您在 JavaScript 中使用内联动画样式,这可能会干扰 CSS 悬停效果。相反,使用 CSS 类:

    btn.addEventListener("mouseenter", () => {
      btn.classList.remove("swing-animation");
      void btn.offsetWidth; // Reflow to restart animation
      btn.classList.add("swing-animation");
    });
    btn.addEventListener("mouseleave", () => btn.classList.remove("swing-animation"));
    
  2. 调整大小后按钮会起作用,因为浏览器会重新计算布局。我会重述 React 如何处理这些操作。强制执行此操作

    useEffect
    :

    useEffect(() => {
      const navButtons = document.querySelectorAll(".nav-button");
      navButtons.forEach((btn) => btn.offsetHeight); // reflow
    }, []);
    
  3. 如果在较少的选项卡上效果更好,则浏览器可能会限制资源。添加硬件加速:

    * {
      will-change: transform, opacity;
    }
    

Obv,如果指针光标缺失,请在 CSS 中显式添加:

.nav-button {
  cursor: pointer !important;
}

更一般地说,我会在没有 GSAP 的情况下运行动画来隔离问题

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