轮播图前端代码 – WAN-P一起制作

轮播图前端代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>平滑滚动轮播图</title>
  <style>
    .slider {
      width: 500px;
      margin: 40px auto;
      text-align: center;
      font-family: Arial, sans-serif;
    }

    .slider-window {
      width: 100%;
      overflow: hidden;
    }

    .slider-track {
      display: flex;
      transition: transform 0.6s ease; /* 平滑滚动动画 */
    }

    .slider-track img {
      width: 500px;
      height: 280px;
      object-fit: cover;
      flex-shrink: 0;
    }

    .indicators {
      margin-top: 10px;
    }

    .indicators span {
      display: inline-block;
      margin: 0 4px;
      padding: 4px 8px;
      border: 1px solid #333;
      cursor: pointer;
      font-size: 14px;
      user-select: none;
    }

    .indicators .active {
      background: #333;
      color: #fff;
    }
  </style>
</head>
<body>

<div class="slider">
  <div class="slider-window">
    <div class="slider-track" id="slider-track">
      <!-- JS 动态插入图片 -->
    </div>
  </div>
  <div class="indicators" id="indicators">
    <!-- JS 动态插入 1 2 3 4 5 -->
  </div>
</div>

<script>
  const images = [
    '../img/z1.jpg',
    '../img/z2.jpg',
    '../img/z3.jpg',
    '../img/z4.jpg',
    '../img/z5.jpg',
  ];

  const track = document.getElementById('slider-track');
  const indicatorsBox = document.getElementById('indicators');

  // 动态创建图片
  images.forEach(src => {
    const img = document.createElement('img');
    img.src = src;
    track.appendChild(img);
  });

  // 动态创建指示器 1、2、3、4、5
  const indicators = [];
  images.forEach((_, index) => {
    const span = document.createElement('span');
    span.textContent = index + 1;
    if (index === 0) span.classList.add('active');
    span.dataset.index = index;
    indicatorsBox.appendChild(span);
    indicators.push(span);
  });

  let current = 0;
  const slideWidth = 500; // 和 .slider 的宽度一致

  function goToSlide(index) {
    current = index;
    const offset = -current * slideWidth;
    track.style.transform = `translateX(${offset}px)`;

    indicators.forEach(i => i.classList.remove('active'));
    indicators[current].classList.add('active');
  }

  // 指示器点击
  indicators.forEach(span => {
    span.addEventListener('click', () => {
      const index = Number(span.dataset.index);
      goToSlide(index);
    });
  });

  // 自动轮播(可选,想关掉就注释掉这一段)
  setInterval(() => {
    const next = (current + 1) % images.length;
    goToSlide(next);
  }, 3000);
</script>

</body>
</html>

HTML 结构部分

<!DOCTYPE html>
  • 声明文档类型,告诉浏览器这是一个 HTML5 文档。
<html lang="zh-CN">
  • <html> 根标签,包住整页内容。
  • lang="zh-CN" 声明当前页面语言是简体中文,方便搜索引擎和屏幕阅读器。
<head>
  • <head> 头部,放页面配置(编码、标题、样式等),不直接显示在页面中。
  <meta charset="UTF-8">
  • 设置页面的字符编码为 UTF-8,保证中文不会出现乱码。
  <title>平滑滚动轮播图</title>
  • 设置浏览器标签栏上显示的标题文字。
  <style>
  • 内联样式标签,里面写 CSS。

CSS 样式部分

    .slider {
      width: 500px;
      margin: 40px auto;
      text-align: center;
      font-family: Arial, sans-serif;
    }
  • .slider:轮播组件的最外层容器。
  • width: 500px;:整体宽度 500 像素。
  • margin: 40px auto;:上下外边距 40px,左右自动居中,所以整个模块居中显示。
  • text-align: center;:内部文本居中(主要影响下面指示器的文字)。
  • font-family: Arial, sans-serif;:设置字体为 Arial 或其他无衬线字体。
    .slider-window {
      width: 100%;
      overflow: hidden;
    }
  • .slider-window:可视窗口容器,限制显示区域。
  • width: 100%;:宽度占满父容器(也就是 500px)。
  • overflow: hidden;:把超出这个区域的内容隐藏掉,这样左右滑动时只看到当前这一屏。
    .slider-track {
      display: flex;
      transition: transform 0.6s ease; /* 平滑滚动动画 */
    }
  • .slider-track:所有图片所在的滑动轨道。
  • display: flex;:让里面的图片水平排成一行。
  • transition: transform 0.6s ease;:当 transform 变化时,使用 0.6 秒的过渡动画,效果是平滑滚动。
    .slider-track img {
      width: 500px;
      height: 280px;
      object-fit: cover;
      flex-shrink: 0;
    }
  • .slider-track img:轨道里的每一张图片。
  • width: 500px;:每张图片宽度与轮播宽度一致。
  • height: 280px;:统一高度 280 像素。
  • object-fit: cover;:按比例裁剪填满盒子,多余部分裁掉,不会变形。
  • flex-shrink: 0;:在 flex 布局中禁止图片被压缩,保证每张图固定 500px 宽。
    .indicators {
      margin-top: 10px;
    }
  • .indicators:下面装 1、2、3、4、5 的容器。
  • margin-top: 10px;:与轮播图之间留出 10px 间距。
    .indicators span {
      display: inline-block;
      margin: 0 4px;
      padding: 4px 8px;
      border: 1px solid #333;
      cursor: pointer;
      font-size: 14px;
      user-select: none;
    }
  • .indicators span:每个数字按钮。
  • display: inline-block;:既可以像行内元素一样排一行,又可以设置宽高/内边距。
  • margin: 0 4px;:左右间距 4px,让数字之间不要紧贴。
  • padding: 4px 8px;:内边距,让按钮看起来有点块感。
  • border: 1px solid #333;:边框为深灰色细线。
  • cursor: pointer;:鼠标移上去变成小手,提示可点击。
  • font-size: 14px;:调整字体大小。
  • user-select: none;:禁止选中文字,点击更干净。
    .indicators .active {
      background: #333;
      color: #fff;
    }
  • .indicators .active:当前选中的按钮增加 active 类后使用的样式。
  • background: #333;:背景深灰色。
  • color: #fff;:文字变白色,看起来被“选中”。
  </style>
</head>
<body>
  • 结束 <style><head>,开始 <body> 页面主体内容。

轮播 HTML 结构

<div class="slider">
  • 创建轮播组件最外层容器,使用前面定义的 .slider 样式。
  <div class="slider-window">
  • 可视窗口容器,相当于一个“窗口框”,只让你看到当前的那张图。
    <div class="slider-track" id="slider-track">
      <!-- JS 动态插入图片 -->
    </div>
  • class="slider-track":轨道容器,里面本来没有图片,后面用 JS 动态插入。
  • id="slider-track":给它一个 id,方便 JS 用 getElementById 找到。
  • 中间注释说明:这里不在 HTML 里写 <img>,全部由 JS 创建。
  </div>
  <div class="indicators" id="indicators">
    <!-- JS 动态插入 1 2 3 4 5 -->
  </div>
</div>
  • 结束 slider-window
  • <div class="indicators" id="indicators">:指示器容器,下面数字按钮会由 JS 动态创建。
  • 注释说明:JS 生成 1、2、3、4、5。
  • 结束外层 .slider 容器。

JS 脚本部分

<script>
  • 开始写 JavaScript 脚本。
  const images = [
    '../img/z1.jpg',
    '../img/z2.jpg',
    '../img/z3.jpg',
    '../img/z4.jpg',
    '../img/z5.jpg',
  ];
  • 定义一个常量 images,是一个数组,里面存放 5 张轮播图的路径。
  • 每一行都是一个字符串,对应一张图片的位置。
  const track = document.getElementById('slider-track');
  • 从 DOM 中获取 id 为 slider-track 的元素,也就是图片轨道容器。
  • 赋值给常量 track,后面要往里塞 <img>,并控制它的 transform
  const indicatorsBox = document.getElementById('indicators');
  • 获取 id 为 indicators 的元素,也就是放 1/2/3/4/5 的容器。
  • 赋值给 indicatorsBox,后面会往里面添加 <span> 标签。

动态创建图片

  // 动态创建图片
  images.forEach(src => {
    const img = document.createElement('img');
    img.src = src;
    track.appendChild(img);
  });

逐行解释:

  • images.forEach(src => { ... });
    • 遍历 images 数组,每次循环把当前项赋给 src(图片路径)。
    • forEach 是数组的遍历方法,不返回新数组,只执行回调。
  • const img = document.createElement('img');
    • 每次循环创建一个新的 <img> 元素。
    • document.createElement('img') 用 JS 在内存中生成一个 img 标签。
  • img.src = src;
    • 设置图片的 src 属性为当前这张图片路径。
    • 这样 <img> 就知道要显示哪张图。
  • track.appendChild(img);
    • 把这个新建的 <img> 插入到 track 容器的最后面。
    • 最终形成一个横向排布的图片队列。

动态创建指示器(1、2、3、4、5)

  // 动态创建指示器 1、2、3、4、5
  const indicators = [];
  • 注释说明这段是创建下面的数字按钮。
  • const indicators = []; 创建一个空数组,用来存所有创建好的 <span> 指示器,后面需要操作它们的样式和事件。
  images.forEach((_, index) => {
    const span = document.createElement('span');
    span.textContent = index + 1;
    if (index === 0) span.classList.add('active');
    span.dataset.index = index;
    indicatorsBox.appendChild(span);
    indicators.push(span);
  });

逐行解释:

  • images.forEach((_, index) => { ... });
    • 再次遍历 images 数组,这次我们只需要索引 index,所以第一个参数写 _ 表示“我不关心这个值”(图片路径)。
    • index 从 0 到 4,对应第 1 到第 5 张图。
  • const span = document.createElement('span');
    • 创建一个新的 <span> 元素,作为一个数字按钮。
  • span.textContent = index + 1;
    • 设置 span 的文本内容为 index + 1,也就是 1、2、3、4、5。
    • 注意 index 从 0 起,所以要加 1 给用户看。
  • if (index === 0) span.classList.add('active');
    • 如果是第一个按钮(index 为 0),给它加上 active 类。
    • 这样初始状态下第一个按钮是高亮的,对应第一张图默认显示。
  • span.dataset.index = index;
    • 给 span 设置一个自定义属性 data-index
    • 写成 JS 是 dataset.index,写到 HTML 就是 data-index="0" 这样。
    • 后面点击的时候,会通过这个 index 找到要切换到第几张图片。
  • indicatorsBox.appendChild(span);
    • 把这个 span 挂到页面中的 indicatorsBox 容器里。
  • indicators.push(span);
    • 把这个 span 保存到 indicators 数组中,之后切换时需要统一操作所有按钮的样式。

当前索引与每张幻灯片宽度

  let current = 0;
  • 定义变量 current,记录当前显示的是第几张图片。
  • 初始设为 0,表示第一张(因为数组下标从 0 开始)。
  const slideWidth = 500; // 和 .slider 的宽度一致
  • 定义常量 slideWidth,表示每一张幻灯片的宽度。
  • 填写的是 500,与 CSS 中 .slider.slider-track img 的宽度一致。
  • 用来计算轨道要向左移动多少像素。

切换图片的核心函数

  function goToSlide(index) {
    current = index;
    const offset = -current * slideWidth;
    track.style.transform = `translateX(${offset}px)`;

    indicators.forEach(i => i.classList.remove('active'));
    indicators[current].classList.add('active');
  }

逐行解释:

  • function goToSlide(index) { ... }
    • 定义一个函数,用来跳转到指定序号的图片。
    • 参数 index 是目标图片的下标(0~4)。
  • current = index;
    • 更新当前索引 current 为要跳转到的这一张。
  • const offset = -current * slideWidth;
    • 计算轨道需要平移的距离。
    • 比如当前是第 2 张(index=1),offset = -1 * 500 = -500 像素,表示整体左移 500px,让第二张对齐窗口。
  • track.style.transform = translateX(${offset}px);
    • 设置轨道的 CSS transform 属性为平移。
    • 利用 CSS 里写好的 transition: transform 0.6s ease;,会产生平滑动画。
  • indicators.forEach(i => i.classList.remove('active'));
    • 遍历所有按钮,把它们的 active 类全部移除,先清空高亮状态。
  • indicators[current].classList.add('active');
    • 再给当前这一项(新的 current)添加 active 类,表示现在这一张是选中状态,对应数字高亮。

给指示器添加点击事件

  // 指示器点击
  indicators.forEach(span => {
    span.addEventListener('click', () => {
      const index = Number(span.dataset.index);
      goToSlide(index);
    });
  });

逐行解释:

  • 注释:说明下面代码是处理“点击下面1、2、3、4、5”的逻辑。
  • indicators.forEach(span => { ... });
    • 遍历存好的所有 span 按钮。
  • span.addEventListener('click', () => { ... });
    • 给每个按钮注册一个点击事件监听器。
    • 当用户点击某个数字时,会触发回调函数。
  • const index = Number(span.dataset.index);
    • 从该按钮的自定义属性 data-index 里取出对应的下标。
    • span.dataset.index 返回字符串,需要用 Number() 转成数字。
  • goToSlide(index);
    • 调用前面写好的切换函数,切到对应的图片。

自动轮播部分(定时切换)

  // 自动轮播(可选,想关掉就注释掉这一段)
  setInterval(() => {
    const next = (current + 1) % images.length;
    goToSlide(next);
  }, 3000);

逐行解释:

  • 注释说明:这是自动轮播,如果不想自动切换,可以整段注释掉。
  • setInterval(() => { ... }, 3000);
    • 设置一个定时器,每隔 3000 毫秒(3 秒)执行一次回调函数。
    • 实现“每 3 秒自动切换到下一张”。
  • const next = (current + 1) % images.length;
    • 计算下一张图片的下标:
      • current + 1:当前索引加 1。
      • % images.length:模运算,让它超过最后一张时从 0 重新开始。
      • 比如 current 是 4(最后一张),(4+1) % 5 = 0,回到第一张。
  • goToSlide(next);
    • 调用切换函数,切换到下一张图片。
</script>

</body>
</html>
  • 结束 <script>
  • 结束 <body><html>,页面结构结束。

留下评论