1. 轮播器效果图
1. 正常状态下每 1.5秒 自动轮播下张图片,轮播结束从头开始重复

2. 鼠标悬停时停止轮播,可以选择左右图片切换

2. HTML 结构
- 文档类型声明:
<!DOCTYPE html>
声明文档类型为HTML5。 - HTML标签:
<html lang="zh-CN">
表示这是一个中文的HTML文档。 - 头部:
<head>
标签内包含了文档的元数据。
<meta charset="UTF-8">
指定文档的字符编码为UTF-8。<meta name="viewport" content="width=device-width, initial-scale=1.0">
用于优化移动设备上的显示效果。<title>
标签定义了文档的标题,这里为“Picture carousel”。
- 样式:
<style>
标签内定义了CSS样式,用于美化轮播图。 - 主体:
<body>
标签内包含了页面的所有内容。
.slider
类定义了轮播图的整体样式和位置。.slide-track
类定义了包含所有幻灯片的轨道。.slide
类定义了单个幻灯片的样式。.prev
和 .next
类定义了上一张和下一张图片的控制按钮样式。.indicators
类定义了轮播指示器的容器样式。.indicator
类定义了单个指示器的样式。
- 图片和按钮:
<div class="slide">
标签包含了图片。<span class="prev">
和 <span class="next">
是控制按钮,点击时调用JavaScript函数 moveSlide
。
- 指示器容器:
<div class="indicators"></div>
用于存放指示器。
3. CSS 样式
.slider
:定义了轮播图容器的宽度、边距、溢出隐藏、相对定位和阴影效果。.slide-track
:定义了轨道的布局方式(不换行)、过渡效果和将改变的内容(优化性能)。.slide
:定义了幻灯片的大小、背景、文字样式和过渡效果。.slide img
:定义了图片的填充方式,使其覆盖整个幻灯片区域。.prev, .next
:定义了控制按钮的基本样式,包括指针、定位、颜色、背景和过渡效果。.slider:hover .prev, .slider:hover .next
:定义了鼠标悬停时控制按钮的透明度。.indicators
:定义了指示器容器的位置和文本对齐方式。.indicator
:定义了单个指示器的大小、边距、背景色、圆角和指针样式。.indicator.active
:定义了激活状态下的指示器背景色。
4. JavaScript 脚本
- 变量定义:定义了当前索引、幻灯片元素、总幻灯片数、幻灯片宽度和相关DOM元素。
- 创建指示器:循环创建指示器,并为每个指示器添加点击事件,用于切换幻灯片。
- 更新幻灯片位置:
updateSlidePosition
函数根据当前索引更新幻灯片轨道的位置。 - 更新指示器状态:
updateIndicators
函数用于更新指示器的激活状态。 - 移动幻灯片:
moveSlide
函数用于根据传入的方向参数来更新当前索引,并调用更新函数。 - 自动轮播:设置定时器
autoSlideInterval
,每隔一定时间自动切换幻灯片。 - 鼠标悬停事件:为轮播图容器添加鼠标悬停事件监听器,用于在鼠标悬停时停止自动轮播,在鼠标离开时重新开始。
4. 源代码
| <!DOCTYPE html> |
| <html lang="zh-CN"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Picture carousel</title> |
| <style> |
| .slider { |
| width: 600px; |
| margin: 50px auto; |
| overflow: hidden; |
| position: relative; |
| box-shadow: 0 4px 10px rgba(0,0,0,0.4); |
| } |
| .slide-track { |
| white-space: nowrap; |
| transition: transform 0.5s ease-in-out; |
| will-change: transform; |
| } |
| .slide { |
| display: inline-block; |
| width: 600px; |
| height: 300px; |
| background: #000; |
| color: #fff; |
| text-align: center; |
| line-height: 300px; |
| font-size: 30px; |
| transition: opacity 0.5s ease-in-out; |
| } |
| .slide img { |
| width: 100%; |
| height: 100%; |
| object-fit: cover; |
| } |
| .prev, .next { |
| cursor: pointer; |
| position: absolute; |
| top: 50%; |
| transform: translateY(-50%); |
| font-size: 18px; |
| color: white; |
| background: rgba(0, 0, 0, 0.5); |
| padding: 10px; |
| z-index: 100; |
| opacity: 0; |
| transition: opacity 0.3s ease-in-out; |
| } |
| .next { |
| right: 0; |
| } |
| .slider:hover .prev, |
| .slider:hover .next { |
| opacity: 1; |
| } |
| .indicators { |
| position: absolute; |
| bottom: 10px; |
| left: 50%; |
| transform: translateX(-50%); |
| text-align: center; |
| } |
| .indicator { |
| display: inline-block; |
| width: 10px; |
| height: 10px; |
| margin: 0 5px; |
| background-color: #bbb; |
| border-radius: 50%; |
| cursor: pointer; |
| } |
| .indicator.active { |
| background-color: #717171; |
| } |
| </style> |
| </head> |
| <body> |
| <div class="slider"> |
| <div class="slide-track"> |
| |
| <div class="slide"><img src="./CSS.jpg" alt="Image 1"></div> |
| <div class="slide"><img src="./nginx.jpg" alt="Image 2"></div> |
| <div class="slide"><img src="./ssl.jpg" alt="Image 3"></div> |
| |
| </div> |
| <span class="prev" onclick="moveSlide(-1)">❮</span> |
| <span class="next" onclick="moveSlide(1)">❯</span> |
| <div class="indicators"></div> |
| </div> |
| |
| <script> |
| let currentIndex = 0; |
| const slides = document.querySelectorAll('.slide'); |
| const totalSlides = slides.length; |
| const slideWidth = 600; |
| const slideTrack = document.querySelector('.slide-track'); |
| const indicatorsContainer = document.querySelector('.indicators'); |
| |
| |
| for (let i = 0; i < totalSlides; i++) { |
| const indicator = document.createElement('div'); |
| indicator.classList.add('indicator'); |
| if (i === 0) indicator.classList.add('active'); |
| indicator.addEventListener('click', () => { |
| currentIndex = i; |
| updateSlidePosition(); |
| updateIndicators(); |
| }); |
| indicatorsContainer.appendChild(indicator); |
| } |
| |
| function updateSlidePosition() { |
| slideTrack.style.transform = `translateX(-${currentIndex * slideWidth}px)`; |
| } |
| |
| function updateIndicators() { |
| document.querySelectorAll('.indicator').forEach((indicator, index) => { |
| if (index === currentIndex) { |
| indicator.classList.add('active'); |
| } else { |
| indicator.classList.remove('active'); |
| } |
| }); |
| } |
| |
| function moveSlide(direction) { |
| currentIndex += direction; |
| if (currentIndex >= totalSlides) { |
| currentIndex = 0; |
| } else if (currentIndex < 0) { |
| currentIndex = totalSlides - 1; |
| } |
| updateSlidePosition(); |
| updateIndicators(); |
| } |
| |
| |
| let autoSlideInterval = setInterval(() => { |
| moveSlide(1); |
| }, 2500); |
| |
| |
| const slider = document.querySelector('.slider'); |
| slider.addEventListener('mouseenter', () => clearInterval(autoSlideInterval)); |
| slider.addEventListener('mouseleave', () => autoSlideInterval = setInterval(() => moveSlide(1), 2000)); |
| |
| |
| updateSlidePosition(); |
| </script> |
| </body> |
| </html> |
复制