打造一个简洁高效的jQuery轮播图
在现代网页设计中,轮播图(Carousel)是一个常见且有效的元素,用于展示多张图片或内容。分享一个最近实现的简洁高效的jQuery轮播图。
轮播图的特点
- 响应式设计:适应不同屏幕尺寸
- 自动播放:每3秒自动切换到下一张图片
- 手动控制:用户可以通过点击指示器来切换图片
- 平滑过渡:使用CSS transition实现流畅的切换效果
- 暂停功能:鼠标悬停时暂停自动播放
- 文字提示:每个图都能配上title
实现原理
这个轮播图主要由HTML结构、CSS样式和jQuery代码两部分组成。
HTML结构非常简单,主要包含两个部分:
- 图片容器(.box-1)
- 指示器(.box-2)
<div class="carousel">
<h2><span class="red-line">轮播图</span></h2>
<div>
<div class="box">
<div class="box-1">
<ul class="gallery">
<!-- 图片项会动态插入这里 -->
</ul>
</div>
<div class="box-2">
<ul>
<!-- 指示器项会动态插入这里 -->
</ul>
</div>
</div>
</div>
</div>
CSS样式
CSS样式主要用于设置轮播图的外观和动画效果。关键的样式包括:
- 使用padding-bottom来保持16:9的宽高比
- 使用绝对定位来叠放图片
- 使用CSS transition来实现平滑的切换效果
.carousel .box {
width: 100%;
max-width: 800px;
height: 0;
padding-bottom: 50%; /* 保持16:9的宽高比 */
margin: 20px auto;
overflow: hidden;
position: relative;
border: 1px solid #ccc;
}
.carousel .box-1 ul li {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
transition: left 0.5s ease-in-out;
}
jQuery代码
jQuery代码负责轮播图的动态效果,包括:
- 动态生成图片列表和指示器
- 实现自动播放功能
- 处理用户交互(点击指示器和箭头)
- 实现图片切换动画
核心的切换函数如下:
function go(target, direction) {
if (target === current) return;
var currentSlide = $box1.eq(current);
var targetSlide = $box1.eq(target);
if (direction !== 'right') {
direction = 'left';
}
currentSlide.css({left: '0'}).animate({left: direction === 'left' ? '-100%' : '100%'}, 500);
targetSlide.css({left: direction === 'left' ? '100%' : '-100%'}).show().animate({left: '0'}, 500, function() {
$box1.not(currentSlide).not(targetSlide).css({left: direction === 'left' ? '100%' : '-100%', display: 'none'});
});
$box2.children().removeClass("on").eq(target).addClass("on");
current = target;
}
完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
.carousel {
width: 600px; /* 根据需要设置宽度 */
height: calc(100vw * 9 / 16); /* 16:9 的比例 */
max-height: 100%; /* 确保高度不会超过视窗 */
margin: 0 auto;
}
.carousel .box * {
padding: 0;
margin: 0;
font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
font-size: 14px;
}
.carousel .box ul, li {
list-style: none;
}
.carousel .box a {
text-decoration: none;
color: black;
}
.carousel .box {
width: 100%;
max-width: 800px;
height: 0;
padding-bottom: 50%;
margin: 20px auto;
overflow: hidden;
position: relative;
border: 1px solid #ccc;
}
.carousel .box-1 ul li {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
.carousel .box-1 ul li img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.carousel .box-1 ul li h2 {
position: absolute;
left: 0;
bottom: 5px;
width: 100%;
background: rgba(125,125,120,.4);
padding: 0 2%;
font-size: 15px;
text-overflow: ellipsis;
font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", sans-serif;
overflow: hidden;
white-space: nowrap;
font-weight: 500;
color: ghostwhite;
box-sizing: border-box;
height: 15%;
display: flex;
align-items: center;
line-height: 1.2;
letter-spacing: 0.5px;
text-shadow: 0 0 1px rgba(0,0,0,0.3);
text-rendering: optimizeLegibility;
}
.carousel .box-2 {
position: absolute;
right: 2%;
bottom: 3.5%;
}
.carousel .box-2 ul li {
float: left;
width: 12px;
height: 12px;
overflow: hidden;
margin: 0 5px;
border-radius: 50%;
background: rgba(0,0,0,0.5);
text-indent: 100px;
cursor: pointer;
}
.carousel .box-2 ul .on {
background: rgba(255,255,255,0.6);
}
.carousel .box-1 ul li {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
transition: left 0.5s ease-in-out;
}
.carousel .box-1 ul li img {
display: block;
width: 100%;
height: 100%;
object-fit: fill;
}
.carousel h2 {
text-align: center;
margin-bottom: 10px;
}
.carousel .red-line {
border-bottom: 2px solid red;
padding-bottom: 5px;
}
</style>
</head>
<body>
<div class="carousel">
<h2><span class="red-line">轮播图</span></h2>
<div>
<div class="box">
<div class="box-1">
<ul class="gallery">
</ul>
</div>
<div class="box-2">
<ul>
</ul>
</div>
</div>
</div>
</div>
<script>
// 模拟数据获取函数
function getActivity() {
return new Promise((resolve) => {
// 模拟的图片数据
const images = [
{ newsId: 1, src: "http://gips2.baidu.com/it/u=1674525583,3037683813&fm=3028&app=3028&f=JPEG&fmt=auto?w=1024&h=1024", title: "第一张图片标题" },
{ newsId: 2, src: "http://gips3.baidu.com/it/u=100751361,1567855012&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280", title: "第二张图片标题" },
{ newsId: 3, src: "https://gips0.baidu.com/it/u=2946692232,559515331&fm=3028&app=3028&f=JPEG&fmt=auto&q=100&size=f960_1280", title: "第三张图片标题" },
{ newsId: 4, src: "http://gips1.baidu.com/it/u=1025173963,4205445645&fm=3028&app=3028&f=JPEG&fmt=auto?w=3200&h=3200", title: "第四张图片标题" }
];
resolve(images);
});
}
function init() {
//获取图片数据
getActivity().then(images => {
// 动态生成图片列表
var $gallery = $(".box-1 ul.gallery");
$.each(images, function(index, image) {
$gallery.append(`
<li id="${image.newsId}">
<img src="${image.src}">
<h2>${image.title}</h2>
</li>
`);
});
// 动态生成指示器
var $indicator = $(".box-2 ul");
$.each(images, function(index) {
$indicator.append(`<li>${index + 1}</li>`);
});
var $box1 = $(".box-1 ul li");
var $box2 = $(".box-2 ul");
var $box3 = $(".box-3");
var length = $box1.length;
var current = 0;
var timer;
function go(target, direction) {
if (target === current) return;
var currentSlide = $box1.eq(current);
var targetSlide = $box1.eq(target);
// 修改:总是使用左滑,除非明确指定为右滑
if (direction !== 'right') {
direction = 'left';
}
currentSlide.css({left: '0'}).animate({left: direction === 'left' ? '-100%' : '100%'}, 500);
targetSlide.css({left: direction === 'left' ? '100%' : '-100%'}).show().animate({left: '0'}, 500, function() {
// 修改:立即重置未参与动画的图片,无动画效果
$box1.not(currentSlide).not(targetSlide).css({left: direction === 'left' ? '100%' : '-100%', display: 'none'});
});
$box2.children().removeClass("on").eq(target).addClass("on");
current = target; // 确保更新current
}
function autoPlay() {
var nextIndex = (current + 1) % length;
// 修改:只在从最后一张到第一张时使用右滑
var direction = (current === length - 1 && nextIndex === 0) ? 'right' : 'left';
go(nextIndex, direction);
}
timer = setInterval(autoPlay, 3000);
$box1.hover(
function() { clearInterval(timer); },
function() { timer = setInterval(autoPlay, 3000); }
);
$box3.children().hover(
function() { clearInterval(timer); },
function() { timer = setInterval(autoPlay, 3000); }
);
$box2.on("click", "li", function() {
clearInterval(timer);
var index = $(this).index();
// 修改:根据点击的位置决定滑动方向
var direction = index > current ? 'left' : 'right';
go(index, direction);
timer = setInterval(autoPlay, 3000);
});
$box3.children().eq(0).click(function() {
go((current - 1 + length) % length, 'right');
});
$box3.children().eq(1).click(function() {
go((current + 1) % length, 'left');
});
// 初始化显示
$box1.hide().eq(0).show();
$box2.children().eq(0).addClass("on");
});
}
$(document).ready(function() {
init();
});
</script>
</body>
</html>