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

鼠标悬停时循环切换AJAX加载图片,鼠标移出时停止循环

实现模型网格图片悬停轮播效果

嘿,这个需求我太熟了!刚好之前做过类似的产品展示网格,核心就是绑定鼠标事件+定时器控制图片切换+AJAX缓存这几个点,我给你拆解成可直接用的代码和思路:

先理清楚你的HTML结构(补全并规范后)

<div class="c-grid c-grid--models">
  <a href="#link-to-model" class="c-model" data-id="1">
    <figure class="c-model__wrap">
      <img 
        src="http://placeholder.image" 
        data-original="http://lazyloaded.image" 
        class="c-model__img" 
        alt="Model 1"
      >
      <figcaption class="c-model__name">Model Name 1</figcaption>
    </figure>
  </a>
  <!-- 更多模型卡片重复上面的结构,data-id对应不同的模型ID -->
  <a href="#link-to-model-2" class="c-model" data-id="2">
    <figure class="c-model__wrap">
      <img 
        src="http://placeholder.image" 
        data-original="http://lazyloaded.image" 
        class="c-model__img" 
        alt="Model 2"
      >
      <figcaption class="c-model__name">Model Name 2</figcaption>
    </figure>
  </a>
</div>

核心实现思路

  • 给每个.c-model卡片绑定mouseenter和mouseleave事件
  • 进入卡片时:
    1. 先获取当前卡片的data-id,用它请求对应模型的图片列表(缓存请求结果,避免重复AJAX)
    2. 记录原图地址(存在data-original里的)
    3. 启动定时器,每隔1秒切换图片的src
  • 离开卡片时:
    1. 立即清除定时器,停止轮播
    2. 把图片src恢复成原图地址

具体代码实现(jQuery版本,易上手)

// 缓存AJAX请求的结果,避免重复请求
const modelImageCache = {};

$(document).on('mouseenter', '.c-model', function() {
  const $card = $(this);
  const modelId = $card.data('id');
  const $img = $card.find('.c-model__img');
  const originalSrc = $img.data('original');

  // 如果已经缓存过该模型的图片列表,直接用
  if (modelImageCache[modelId]) {
    startImageCycle($img, modelImageCache[modelId], originalSrc);
    return;
  }

  // 没有缓存的话,AJAX请求图片列表
  $.ajax({
    url: `/api/models/${modelId}/images`, // 替换成你的实际接口地址
    method: 'GET',
    success: function(images) {
      // 缓存结果
      modelImageCache[modelId] = images;
      // 启动轮播
      startImageCycle($img, images, originalSrc);
    },
    error: function() {
      console.error(`Failed to load images for model ${modelId}`);
    }
  });
});

$(document).on('mouseleave', '.c-model', function() {
  const $img = $(this).find('.c-model__img');
  const originalSrc = $img.data('original');
  
  // 清除定时器
  clearInterval($img.data('cycleTimer'));
  // 恢复原图
  $img.attr('src', originalSrc);
});

// 封装轮播逻辑的函数
function startImageCycle($img, images, originalSrc) {
  // 如果图片列表为空,直接返回
  if (!images || images.length === 0) return;

  let currentIndex = 0;
  // 先切换到第一张轮播图(跳过原图)
  $img.attr('src', images[currentIndex]);

  // 启动定时器,每隔1秒切换
  const timer = setInterval(() => {
    currentIndex = (currentIndex + 1) % images.length;
    $img.attr('src', images[currentIndex]);
  }, 1000);

  // 把定时器存在图片元素的data里,方便离开时清除
  $img.data('cycleTimer', timer);
}

关键细节优化(必看)

  • 缓存AJAX结果:用modelImageCache对象存每个模型的图片列表,用户再次悬停同个模型时不用重复请求,提升性能
  • 独立定时器:把定时器存在每个图片元素的data里,避免多个卡片的定时器互相干扰
  • 异常处理:AJAX请求失败时打印错误,方便调试
  • 边界情况:如果图片列表为空,直接不启动轮播,避免报错
  • 可选优化:图片预加载:可以在AJAX成功后,提前加载所有轮播图片,避免切换时出现空白:
    // 在AJAX success里添加预加载
    images.forEach(imgUrl => {
      const preloadImg = new Image();
      preloadImg.src = imgUrl;
    });
    

原生JS版本(如果不用jQuery)

如果你项目里没引入jQuery,也可以用原生JS实现,核心逻辑一样,只是事件绑定和DOM操作换成原生API:

const modelImageCache = {};

document.addEventListener('mouseenter', function(e) {
  if (!e.target.closest('.c-model')) return;
  
  const card = e.target.closest('.c-model');
  const modelId = card.dataset.id;
  const img = card.querySelector('.c-model__img');
  const originalSrc = img.dataset.original;

  if (modelImageCache[modelId]) {
    startImageCycle(img, modelImageCache[modelId], originalSrc);
    return;
  }

  fetch(`/api/models/${modelId}/images`)
    .then(res => res.json())
    .then(images => {
      modelImageCache[modelId] = images;
      startImageCycle(img, images, originalSrc);
    })
    .catch(err => console.error(`Failed to load images: ${err}`));
});

document.addEventListener('mouseleave', function(e) {
  if (!e.target.closest('.c-model')) return;
  
  const card = e.target.closest('.c-model');
  const img = card.querySelector('.c-model__img');
  const originalSrc = img.dataset.original;

  clearInterval(img.dataset.cycleTimer);
  img.src = originalSrc;
});

function startImageCycle(img, images, originalSrc) {
  if (!images || images.length === 0) return;

  let currentIndex = 0;
  img.src = images[currentIndex];

  const timer = setInterval(() => {
    currentIndex = (currentIndex + 1) % images.length;
    img.src = images[currentIndex];
  }, 1000);

  img.dataset.cycleTimer = timer;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:36:06