【初试 jQuery】分析轮播图的实现原理,手写轮播图,代码细节分析

效果图

如果想看网页效果,请点击该链接:http://114.55.219.55:8000/ (该链接不保证以后长期有效)

1、从右向左循环滑动

2、可通过左右两端的箭头切换图片(有滑动效果)

3、可底部的小圆圈切换到指定图片(没有滑动效果)

4、图片切换,底部的小圆圈的样式会自动跟着改变

5、鼠标悬停在上面,会停止自动滑动。移除,会自动恢复自动滑动

前言

食用前必看

1、本博客适用人群:有css基础,对jQuery有基本的了解(我也是初学jQuery)

2、如果你使用的素材图大小不一样,自行修改代码中的有关地方。这几张图片我是从慕课网的首页扣下来的。在本博客的末尾,我也贴出来,方便各位拷贝下来。

分析

实现这个轮播图,有一个最关键的难点!这里我分析如何解决这个关键点的原理,其他的坑和注意的点以及容易混乱的细节,我都已经在代码中加上了详细的注释。在明白这个“如何解决这个难点”之后,可直接去结合注释分析代码。

假设,我们轮播显示的只有4张图,这4张图从右向左滑动。滑动一张图后,停留一会,再滑动下面一张。

那么问题是:当前已经显示的是第4张图,如何从第4张图【】回到第1张图(看起来好像无缝衔接)?注意,这里是【滑】回,而不是闪现回到第1张的位置。如果是闪现回到第1张的位置,直接通过设置ul的marginLeft即可实现。

我们可以将第1张图复制一份放到最后(就是说第5张图是第1张图的副本)。假设当前正在显示第4张图,然后第4张图滑动到第5张图。此时第4张图【滑】回到第1张图的动画我们已经看到了,虽然是第1张图的副本,但是视觉上就像是是:第4张图【滑】回到第1张图。此时显示的是第5张图(第1张的副本),此时来个【偷梁换柱】,通过设置ul的marginLeft闪回到真正的第1张的位置。由于副本和第1张一模一样,所以这个【闪回】在视觉上是感受不到的。

如何从第1张【滑】回到第4张呢?

在上面分析了:如何从第4张滑回到第1张,那么“如何从第1张【滑】回到第4张”的道理也是一样的。

假设当前显示的就是第1张,我点击了左端的 “<”。此时来个【偷梁换柱】,通过设置ul的marginLeft一瞬间切换到第5张图(第1张的副本),由于副本和第1张一模一样,所以这个闪现在视觉上是感受不到的。那么再从第1张的副本滑动第4张。那么在视觉上就好像是第1张【滑】回到第4张的假象了。

明白这个原理,就已经成功了一半。剩下就是代码实现,但是这个代码的不少细节都要考虑的比较【细致】,大家可以多多尝试。

代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>轮播图 by passerbyYSQ</title>
<script src="js/jQuery1.4.2.js"></script>

<!-- coded by passerbyYSQ -->

<style>
	* {
		margin: 0px;
		padding: 0px;
		list-style: none;
	}
	#banner {
		width: 936px; /* 刚好为图片真实宽度的一半 */
		height: 382px; /* 刚好为图片真实高度的一半 */
		margin: 50px auto;
		border-radius: 20px;
		overflow: hidden;
		/* border: 1px #000 solid; */ /* 加上边框便于观察 */
		position: relative;
	}
	#banner #bg img {
		width: 936px; /* 图片高度也等比缩小 */
	}
	#banner li {
		float: left;
	}
	#banner #aList li {
		width: 20px;
		height: 20px;
		border-radius: 10px;
		background: rgba(0, 0, 0, 0.5);
		float: left;
		margin: 0px 5px;
	}
	#banner #aList li:hover {
		cursor: pointer;
	}
	#banner #aList {
		position: absolute;
		bottom: 10px;
		left: 50%;
		/* margin-left: -60px; */
	}
	
	#banner .left, #banner .right {
		width: 50px;
		height: 50px;
		border-radius: 25px;
		background: rgba(0, 0, 0, 0.2);
		position: absolute;
		top: 50%;
		margin-top: -25px;
		font-size: 35px;
		font-family: bold;
		color: rgba(255, 255, 255, 0.8);
		text-align: center;
		line-height: 45px;
	}
	#banner .left:hover, #banner .right:hover {
		background: rgba(0, 0, 0, 0.5);
		cursor: pointer;
	}
	#banner .left {
		left: 20px;
	}
	#banner .right {
		right: 20px;
	}
</style>
<script>
	$(function() {				
		// 将#banner #bg中的第一个li复制一份, 放到#banner #bg的最后
		$firstLiCopy = $("#banner #bg li:first").clone(true);
		$("#banner #bg").append($firstLiCopy);
	
		var imgWidth = 936;
		var imgCount = $("#banner #bg li").length;  // 此时, imgCount = 5, 但是实际上我们循环显示的只有4张
		// 为了便于区分说明, 我们声明: 第1张图片为【真正的第1张图片】, 第5张图片为【真正的最后1张图片】
		
		// 动态设置#banner #bg的宽度
		$("#banner #bg").css("width", imgWidth * imgCount);
		// 有多少张图片, 底部就有多个小圆圈
		for (var i = 0; i < imgCount - 1; i++) { // i = 0, 1, 2, 3 < 4
			$("#banner #aList").append($("<li></li>"));
		}
		// 动态纠正#banner #aList, 使其水平居中
		$("#banner #aList").css("marginLeft", - $("#banner #aList").width() / 2);
		
		// 底部小圆圈选中时的样式
		var aSelectedCss = {
						background: "rgba(255, 255, 255, 0.5)",
						width: 30
					};
		// 底部小圆圈未选中时的样式
		var aNoneCss = {
						background: "rgba(0, 0, 0, 0.5)",
						width: 20
					};
		
		// 一开始进来页面, 将底部的第一个小圆圈设置为选中的样式
		$("#banner #aList li").eq(0).css(aSelectedCss);
		
		var stayDuration = 2000; 
		var slideDuration = 500; // 一张图片滑动所需的时间
		var curIndex = 0; // 当前的显示的图片的索引(从0开始)
		
		// 根绝curIndex的变化, 动态设置底部那一排小圆圈的样式变化
		// 在slide方法中被调用
		function setA() {
			// 类推一下。 当第1张图片滑动到第2张图片完成后, 此时curIndex = 1
			// 当第4张图片滑动到第5张图片完成后, 换言之此时刚刚开始显示第5张(第1张的副本), 那么此时的curIndex为多少?
			// 所以那么此时curIndex == imgCount - 1 == 4
			if (curIndex == imgCount - 1) {
				$("#banner #aList li").eq(0).css(aSelectedCss);
				$("#banner #aList li").eq(0).siblings().css(aNoneCss);
				return;
			}
			// 在这里是否需要考虑curIndex < 0的情况? 
			// 不需要!!!
			
			$curA = $("#banner #aList li").eq(curIndex);
			$curA.css(aSelectedCss);
			$curA.siblings().css(aNoneCss);
		}
		
		// 滑动一张图片
		function slide(isToLeft) { // ifToLeft = true : 表示从右向左滑动
			if (isToLeft) {
				curIndex++;
				// 如果curIndex == 2, 说明第1张图片刚刚滑过去, 现在正在显示第2张图片
				// 以此类推
				// 如果curIndex == 5, 说明第4张图片刚刚滑过去, 现在正在显示第5张图片(第5张图片是第一张图片的副本)
				if (curIndex >= imgCount) {
					// 此时偷梁换柱, 一瞬间将位置瞬移到真正的第1张图片
					curIndex = 1; // 第一张已经完成滑过动画了
					$("#banner #bg").css("marginLeft", 0);	
				}
				
				$("#banner #bg").stop().animate({
					//marginLeft: "-=" + imgWidth // 不能使用这个, 否则当连续快速点击"<"会有bug
					marginLeft: - curIndex * imgWidth
				}, slideDuration, function() {
					setA();
				})
			} else {
				curIndex--;
				// 如果curIndex == -1, 说明下面需要执行的动画就是: 【真正的第1张图片】滑动到【真正的最后1张图片】
				// 不过在此之前, 先偷梁换柱, 将位置瞬移到第5张(第1张的副本)的位置
				if (curIndex < 0) { 
					curIndex = imgCount - 2;  // curIndex = 3
					$("#banner #bg").css("marginLeft", - imgWidth * (imgCount-1));
				}
				
				$("#banner #bg").stop().animate({
					//marginLeft: "+=" + imgWidth // 不能使用这个, 否则当连续快速点击">"会有bug
					marginLeft: - curIndex * imgWidth
				}, slideDuration, function() {
					// if (curIndex == -1) 里面已经将curIndex重置为3, 所以在setA里面不要考虑curIndex < 0的情况
					setA();
				})
			}
		}
		
		var timer = null;
		// 开启自动滑动
		function autoPlay() {
			timer = setInterval(function() { // 这里给timer赋值了!!!
				slide(true); // 从右向左滑动
			}, stayDuration); // 先等待再执行
		}
		autoPlay(); // 一进页面, 轮播图自动滑动起来
		
		$("#banner").hover(function() {
			clearInterval(timer); // 鼠标悬停在轮播图(即#banner)时, 清除定时器timer
		}, function() {
			autoPlay(); // 鼠标移出时, 再开一个定时器
		});
		
		// 我们通过底部的小圆圈和左右的"<"和">"来切换图片的时候, 是否会影响和混乱轮播图的自动循环滑动?
		// 不会!! 因为鼠标悬停在轮播图的时候, 我们已经将定时器timer的清除掉了
		$("#banner #aList li").click(function() {
			$(this).css(aSelectedCss);
			$(this).siblings().css(aNoneCss);
			
			curIndex = $(this).index();
			$("#banner #bg").css("marginLeft", - imgWidth * curIndex);
		});
		
		$("#banner .left").click(function() {
			slide(false);
		});
		$("#banner .right").click(function() {
			slide(true);
		});
	});
</script>
</head>
	<body>

			<div id="banner">
				<ul id="bg">
					<li><img src="img/1.jpg"/></li>
					<li><img src="img/2.jpg"/></li>
					<li><img src="img/3.jpg"/></li>
					<li><img src="img/4.jpg"/></li>
				</ul>
				<ul id="aList">
					<!-- <li><a href="#"></a></li>
					<li><a href="#"></a></li>
					<li><a href="#"></a></li>
					<li><a href="#"></a></li> -->
				</ul>
				<div class="left">&lt</div>
				<div class="right">&gt</div>
			</div>
		
	</body>
</html>

素材图:

发布了24 篇原创文章 · 获赞 2 · 访问量 1922

猜你喜欢

转载自blog.csdn.net/qq_43290318/article/details/104540077