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

如何在鼠标悬停轮播中为上一幻灯片设置指定z-index?

问题描述

想要制作一个基于鼠标悬停切换的轮播组件,通过z-index控制幻灯片的显示层级,具体需求如下:

  • 所有幻灯片默认z-index: 1
  • 当前显示的幻灯片设置z-index: 3
  • 切换至新幻灯片时,将上一个幻灯片设为z-index: 2,新幻灯片设为3

当前代码实现如下:

HTML代码

<ul class='slider-navigation'>
  <li data-slide='1'>Slide 1</li>
  <li data-slide='2'>Slide 2</li>
  <li data-slide='3'>Slide 3</li>
</ul>

<div>
  <img class='slide' data-slide='1' src='https://images.unsplash.com/photo-1669818319938-bb7029dc3fa3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzfHx8ZW58MHx8fHw%3D&auto=format&fit=crop&w=500&q=60'>

  <img class='slide' data-slide='2' src='https://images.unsplash.com/photo-1669623313981-6af02eedb15c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw1fHx8ZW58MHx8fHw%3D&auto=format&fit=crop&w=500&q=60'>

  <img class='slide' data-slide='3' src='https://images.unsplash.com/photo-1446776811953-b23d57bd21aa?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTF8fHNwYWNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60' />
</div>

CSS代码

img {
  z-index: var(--z-index);
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 150px;
  object-fit: cover;
}

div {
  height: 200px;
  width: 200px;
  position: relative;
}

img.slideIn {
  animation: slideIn 2s ease forwards;
}

@keyframes slideIn {
  from {
    translate: 200px;
  }
  to {
    translate: 0px;
  }
}

JavaScript代码

slides = document.querySelectorAll('.slide');
navItems = document.querySelectorAll('.slider-navigation li');

navItems.forEach(navItem => {
  navItem.addEventListener('mouseover', () => onNavigationHover(navItem));
});

function onNavigationHover(navItem) {
  let slideKey = navItem.dataset.slide;

  slides.forEach((slide, index) => {
    if (slide.dataset.slide === slideKey) {
      slide.style.setProperty('--z-index', 3)
      // can i set the previous slide zIndex here to 2? 
      slide.classList.add('slideIn')
    } else {
      slide.style.setProperty('--z-index', 1)
      slide.classList.remove('slideIn')
    }
  });
}

当前代码能实现基本切换,但始终有一张图片固定在下层,询问是否可以保存上一个幻灯片的索引并设置不同z-index,或者有其他合适的实现思路。


解决方案

可以通过保存上一个幻灯片的引用来实现需求,以下是两种可行的实现方式:

方式一:通过全局变量记录当前激活幻灯片

核心是维护一个全局变量保存当前显示的幻灯片,每次切换时依次调整层级:

let slides = document.querySelectorAll('.slide');
let navItems = document.querySelectorAll('.slider-navigation li');
let currentActiveSlide = null;

// 初始化:所有幻灯片设为z-index:1,默认激活第一张
slides.forEach(slide => {
  slide.style.setProperty('--z-index', 1);
});
if (slides.length > 0) {
  currentActiveSlide = slides[0];
  currentActiveSlide.style.setProperty('--z-index', 3);
}

navItems.forEach(navItem => {
  navItem.addEventListener('mouseover', () => onNavigationHover(navItem));
});

function onNavigationHover(navItem) {
  let slideKey = navItem.dataset.slide;
  const newActiveSlide = Array.from(slides).find(slide => slide.dataset.slide === slideKey);
  
  // 避免重复触发同一幻灯片
  if (newActiveSlide === currentActiveSlide) return;
  
  // 调整上一个激活幻灯片的层级
  if (currentActiveSlide) {
    currentActiveSlide.style.setProperty('--z-index', 2);
    currentActiveSlide.classList.remove('slideIn');
  }
  
  // 设置新幻灯片的层级与动画
  newActiveSlide.style.setProperty('--z-index', 3);
  newActiveSlide.classList.add('slideIn');
  
  // 将其余幻灯片重置为z-index:1
  slides.forEach(slide => {
    if (slide !== currentActiveSlide && slide !== newActiveSlide) {
      slide.style.setProperty('--z-index', 1);
      slide.classList.remove('slideIn');
    }
  });
  
  // 更新当前激活幻灯片的引用
  currentActiveSlide = newActiveSlide;
}

方式二:通过CSS类控制层级(更易维护)

将层级控制逻辑交给CSS,JS只负责切换类名,符合关注点分离原则:

修改后的CSS

img {
  z-index: 1;
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 150px;
  object-fit: cover;
}

img.active {
  z-index: 3;
}

img.previous {
  z-index: 2;
}

div {
  height: 200px;
  width: 200px;
  position: relative;
}

img.slideIn {
  animation: slideIn 2s ease forwards;
}

@keyframes slideIn {
  from {
    translate: 200px;
  }
  to {
    translate: 0px;
  }
}

对应的JavaScript

let slides = document.querySelectorAll('.slide');
let navItems = document.querySelectorAll('.slider-navigation li');

// 初始化激活第一张幻灯片
if (slides.length > 0) {
  slides[0].classList.add('active');
}

navItems.forEach(navItem => {
  navItem.addEventListener('mouseover', () => {
    const slideKey = navItem.dataset.slide;
    const newActiveSlide = Array.from(slides).find(s => s.dataset.slide === slideKey);
    
    if (newActiveSlide.classList.contains('active')) return;
    
    // 将当前激活幻灯片标记为上一张
    const currentActive = document.querySelector('.slide.active');
    if (currentActive) {
      currentActive.classList.remove('active');
      currentActive.classList.add('previous');
      currentActive.classList.remove('slideIn');
    }
    
    // 清除其他幻灯片的上一张标记
    slides.forEach(slide => {
      if (slide !== currentActive) {
        slide.classList.remove('previous');
      }
    });
    
    // 设置新幻灯片为当前激活状态
    newActiveSlide.classList.add('active');
    newActiveSlide.classList.add('slideIn');
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:40:27