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

Angular如何实现鼠标悬停时平滑逐张切换img标签src

原有代码问题点
  • 错误使用setInterval做定时切换,该API会无限循环执行,且没有做定时器清理,鼠标多次悬停后会出现多个定时器堆叠,图片切换节奏完全混乱
  • 没有做图片预加载,切换到对应路径时才发起资源请求,会出现加载空白、卡顿
  • 没有绑定鼠标移出事件,悬停结束后不会重置回初始状态
  • 没有加CSS过渡效果,图片切换是硬跳变,没有平滑过渡的视觉效果
  • 没有保存定时器引用,无法在不需要时清除,会造成内存泄漏
完整修正实现

TypeScript 逻辑

import { Component, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-logo',
  templateUrl: './logo.component.html',
  styleUrls: ['./logo.component.css']
})
export class LogoComponent implements OnDestroy {
  logoData = [
    "assets/img/logoState1.png",
    "assets/img/logoState2.png",
    "assets/img/logoState3.png",
    "assets/img/logoState4.png",
    "assets/img/logoState5.png",
  ];

  imgSrc: string = this.logoData[0];
  private switchTimer: number | null = null;
  private currentIndex = 0;
  // 单张切换间隔,可根据需要调整速度
  private readonly switchDelay = 180;

  constructor() {
    // 预加载所有图片资源,避免切换时加载卡顿
    this.logoData.forEach(src => {
      const tempImg = new Image();
      tempImg.src = src;
    });
  }

  // 鼠标悬停启动逐帧切换
  onHoverStart(): void {
    this.clearExistTimer();
    this.currentIndex = 0;
    this.loopSwitch();
  }

  // 逐帧切换逻辑
  private loopSwitch(): void {
    this.switchTimer = window.setTimeout(() => {
      this.currentIndex++;
      // 到最后一帧停止,如需循环播放可将索引重置为0
      if (this.currentIndex >= this.logoData.length) {
        this.currentIndex = this.logoData.length - 1;
        return;
      }
      this.imgSrc = this.logoData[this.currentIndex];
      this.loopSwitch();
    }, this.switchDelay);
  }

  // 鼠标移出重置状态
  onHoverEnd(): void {
    this.clearExistTimer();
    this.currentIndex = 0;
    this.imgSrc = this.logoData[0];
  }

  // 统一清理定时器
  private clearExistTimer(): void {
    if (this.switchTimer) {
      clearTimeout(this.switchTimer);
      this.switchTimer = null;
    }
  }

  ngOnDestroy(): void {
    this.clearExistTimer();
  }
}

HTML 模板

<div class="logoContainer">
  <img
    class="img-fluid logo-base"
    [src]="imgSrc"
    (mouseenter)="onHoverStart()"
    (mouseleave)="onHoverEnd()"
  />
</div>

CSS 样式(加平滑过渡)

.logoContainer {
  width: fit-content;
  cursor: pointer;
}

.logo-base {
  display: block;
  transition: opacity 0.12s ease-in-out;
  opacity: 1;
}
效果说明
  • 所有图片在组件初始化时就提前加载完成,切换时无加载等待,不会出现闪烁空白
  • 每次触发悬停都会先清理之前的定时器,不会出现多定时器串扰、切换节奏混乱的问题
  • 增加了透明度过渡动画,图片切换时不会生硬跳变,视觉上更流畅
  • 鼠标移出区域后会自动重置回初始第一帧状态,交互闭环完整
  • 切换速度可以通过修改switchDelay参数自由调整,适配不同的动效需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:01:04