分享一个手写轮播图的学习案例

首先确定需求。
做一个仿照淘宝首页的轮播图有以下需求:
①.鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。
②.点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理。
③.图片播放的同时,下面小圆圈模块跟随一起变化。
④.点击小圆圈,可以播放相应图片。
⑤.鼠标不经过轮播图,轮播图也会自动播放图片。
⑥.鼠标经过,轮播图模块, 自动播放停止。
确定需求之后先用HTML和CSS把结构搭建好,这个案例重点在于JavaScript的操作。
我在写代码的时候注释的都比较详细了,在这里就不讲了。
这个案例的主要js文件如下:

//让Window的结构加载完再执行JS
window.addEventListener ('load',function(){
	var arr_l = document.querySelector(".arr_l");
	var arr_r = document.querySelector(".arr_r");
	var focus = document.querySelector(".focus");
	var t= null;
	var num = 0;
	t = setInterval(function(){
			arr_r.click();
		},1000);
	//①第一个功能:鼠标离开时隐藏两侧图标,鼠标进入时显示
	focus.addEventListener("mouseenter",function(){
		arr_l.style.display = "block";
		arr_r.style.display = "block";
		//当鼠标经过时,让它停止自动播放,即隔清除计时器
		clearInterval(t);
		t = null;
	});
	focus.addEventListener("mouseleave",function(){
		arr_l.style.display = "none";
		arr_r.style.display = "none";
		//当鼠标离开时,让它自动播放,即隔一段时间调用一下点击右侧时间
		t = setInterval(function(){
			arr_r.click();
		},1000);
	});
	//②动态生成小圆圈,使它和图片的数目一致
	//③点击小圆圈,当前小圆圈变实心。用排他思想
	var lis = document.querySelectorAll(".box li");
	var box = document.querySelector(".box");
	var circle = document.querySelector(".circle");
	for(var i=0;i<lis.length;i++){
		var li = document.createElement("li");
		li.setAttribute("data_index",i);
		li.addEventListener("click",function(){
			for(var i = 0;i<circle.children.length;i++){
				circle.children[i].className = "";
			}
			this.className = "current";
			//④点击圆圈图片滑动
			var index = this.getAttribute("data_index")
			var target = -index * box.children[0].clientWidth;
			animate(box,target);
		});
		circle.appendChild(li);
	}
	//默认第一个圆圈为实心
	circle.children[0].className = "current";
	
	/*
	 * 为了让最后一张图片跳到第一张图片的时候更顺畅,可以把第一张图片复制到第四张的后面
	 * 如果在最后一张的时候点击了后一张,那么显示复制的那张图片,而小圆圈变成第一个
	 * 这样看起来会跟连贯,像一个循环一样
	 */
	var first = box.children[0].cloneNode(true);
	box.appendChild(first);
	/*
	 * 设置一个num值,每次点击加1.从而每次点击的目标位置就是-num* box.children[0].clientWidth
	 */
	var cir = 0;   //用cir来控制小圆圈变化
	//注册右侧按钮事件
	/*
	 * 这里为了防止点击过快导致播放过快,要设置一个节流阀,让上一个动画执行完毕才能开始下一个动画。
	 */
	var flag = true;
	arr_r.addEventListener("click",function(){
		/*
		 * 当num=box.children.length-1 时,即图片播放到了最后一张。
		 * 当已经播放到最后一张时,此时若右侧按钮再被点击,
		 * 则马上让num=0,让box的lfet值设为0,让它显示第一张图片。
		 * 但是后面还会执行一次animate(box,-num * box.children[0].clientWidth);
		 * 所以播放起来就会像是一个循环
		 */
		if(flag){
			flag = false;  //关闭节流阀
			if(num==box.children.length-1){
				box.style.left = 0;
	            num = 0;
			}
			num++;
			//在动画函数的回调函数里把节流阀打开,这样确保是在动画完毕后,才能开始下一个动画
			animate(box,-num * box.children[0].clientWidth,function(){
				flag = true;
			});
			//点击按钮让图片滑动时,应该让小圆圈也对应显示
			cir++;
			if(cir == circle.children.length){
				cir=0;
			}
			changeCircle();
		}		
	});
	//注册左侧事件
	arr_l.addEventListener("click",function(){
		if(flag){
			flag=false;
			if(num==0){
				box.style.left = box.children.length-1;
	            num = box.children.length-1;
			}
			num--;
			animate(box,-num * box.children[0].clientWidth,function(){
				flag=true;
			});
			//点击按钮让图片滑动时,应该让小圆圈也对应显示
			cir--;
			if(cir<0){
				cir=circle.children.length-1;
			}
			changeCircle();
		}
	});
	/*
	 * 控制小圆圈变化的函数
	 */
	function changeCircle(){
		for(var i = 0;i<circle.children.length;i++){
				circle.children[i].className = "";
			}
			circle.children[cir].className = "current";
	}
});

还有一个滑动动画的函数放在这个文件夹里:

function animate(obj,target,callback){
	//在每次点击时先清除上一次的计时器,这样就不会出现连续点击会让盒子走的太快
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
		var step = (target - obj.offsetLeft) / 5;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);//给每一步的距离取整,避免出现小数,导致最后终点和target不一样
		obj.style.left = obj.offsetLeft + step + "px";
		if(obj.offsetLeft==target){
			clearInterval(obj.timer);
			callback && callback();//如果有callback则执行,没有则不执行
		}
	},50);
}

最后的运行结果如下:

轮播图效果

(PS如果有需要源文件的小伙伴可以私信我)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值