原生js实现多功能可滑动轮播图

效果图:

原生js实现多功能可滑动轮播图_第1张图片

这次做的轮播图,值得注意的主要功能有:

1、滑动动画切换效果(无缝衔接);

2、标签和略缩图点击切换效果(自适应性滑动,不同距离滑动速度不同);

3、自动循环播放;

4、鼠标悬浮在轮播图上时停止自动播放。

难点:

1、循环滑块动画切换效果,主要的算法也集中在这里。我的方法是前后多放一张图,然后在切换结束后的一刻瞬间改变参数,这样就不会有一闪而过同时还能无缝衔接的效果;

2、在轮播图滑动过程中,不应该再响应鼠标点击,这个功能用flag来处理;

3、标签和略缩图自适应性切换时,切换速度是根据当前标签和已有标签之间的距离变的,本来想在闭包中多调用几次next_pic,但是由于带定时器的函数总是最后执行,故这种方法pass,解决方法是另外写一个自适应性函数。

下面上代码:

html:




	风景轮播图
	
	


	
1
2
3
4
5

 

css:

/*------------------------公共样式表----------------------------*/
* {
	margin: 0px;
	padding: 0px;
	border: 0px;
}
a {
	text-decoration: none;
}
/*------------------------内容样式表----------------------------*/
/*显示类*/
#container {
	position: relative;
	width: 600px;
	height: 400px;
	overflow: hidden;
	margin: 5px auto;
}
/*卷轴类*/
#wrap {
	position: absolute;
	width: 4200px;
	height: 400px;
	z-index: 1;
}
.img-wrap {
	display: block;
    float: left;
	width: 600px;
	height: 400px;
}
/*序号标签类*/
#tag-bkg {
	position: absolute;
    width: 600px;
    height: 20px;
    top: 370px;
    background-color: transparent;
    display: flex;
    justify-content: center;
    align-content: center;
    z-index: 2;
}
.tag {
    width: 20px;
    height: 20px;
    color: white;
    font-size: 15px;
    margin-left: 10px;
    border-radius: 50%;
    text-align: center;
    cursor: pointer;
}
.tag-off {
	background-color: orange;
}
.tag-on {
	background-color: red;
}
/*箭头类*/
.arrow {
	position: absolute;
    width: 40px;
    height: 70px;
    border-radius: 50%;
    top: 170px;
    z-index: 2;
}
.arrow-left {
	left: 10px;
}
.arrow-right {
	right: 10px;
}
/*------------------------略缩图样式表----------------------------*/
#thumb_bkg {
	position: relative;
	width: 600px;
	height: 80px;
	/*background-color: blue;*/
	margin: 5px auto;
}
.thumb {
	display: block;
    float: left;
	width: 120px;
	height: 80px;
	cursor: pointer;
}

.thumb-off {
	opacity: 0.5;
}
.thumb-on {
	opacity: 1.0;
}

 

js:

// 对象变量声明
var index = 1;//索引
//var value = 4;//行走方向及距离,正数为向前走,负数为向后走,数值代表走的距离,这里默认为4px
var flag = 0;//flag为0时表示可以点击,为1时表示正在移动,鼠标无法点击
var ap_time, go_time;//定时器对象
var start = 0, end = -600, procession = -600;//各种距离变量
var wrap = document.getElementById("wrap");
var prev = document.getElementsByClassName("arrow-left");
var next = document.getElementsByClassName("arrow-right");
var tags = document.getElementsByClassName("tag");
var thumbs = document.getElementsByClassName("thumb");
// 各种函数
// 显示当前索引标签
function showCurrentThumbsandTags() {
	for (var i = 0; i < tags.length; i++) {
		tags[i].className = "tag tag-off";
		thumbs[i].className = "thumb thumb-off";
	}
	if(index > 0) {
		tags[(index-1)%5].className = "tag tag-on";
		thumbs[(index-1)%5].className = "thumb thumb-on";
	}
	else {
		tags[(5-Math.abs(index-1))%5].className = "tag tag-on";
		thumbs[(5-Math.abs(index-1))%5].className = "thumb thumb-on";
	}
}
//滚动效果
function go(value) {
	flag = 1;
	go_time = setInterval(gostep, 1, value);
}
//滚动效果细化
function gostep(value) {
	//console.log(99999,value);
	procession = procession + value;
	wrap.style.left = procession + "px";
	// console.log(value, 888888)
	// console.log(end,procession,"   666");
	// console.log(index);
	// console.log(wrap.style.left);
	// console.log(start);
	// console.log(end);
	// console.log(procession);
	if(procession == end) {
		clearInterval(go_time);
		flag = 0;
		if(index == 6) {
			index = 1;
			start = 0;
			end = -600;
			procession = -600;
			wrap.style.left = -600 + "px";
		}
		if(index == 0) {
			index = 5;
			start = -3600;
			end = -3000;
			procession = -3000;
			wrap.style.left = -3000 + "px";
		}
	}
}
//向前翻页
function prev_pic(value) {
	index--;
	value = Math.abs(value);
	start = end;
	end = start+600;
	go(value);
	showCurrentThumbsandTags();
}
//适应性向前翻页
function adj_prev_pic(value) {
	var multiple = value/4;
	index = index - multiple;
	value = Math.abs(value);
	start = end;
	end = start + 600*multiple;
	go(value);
	showCurrentThumbsandTags();
}
//向后翻页
function next_pic(value) {
	index++;
	value = Math.abs(value)*(-1);
	start = end;
	end = start-600;
	go(value);
	showCurrentThumbsandTags();
}
//适应性向后翻页
function adj_next_pic(value) {
	var multiple = value/4;
	index = index + multiple;
	value = Math.abs(value)*(-1);
	start = end;
	end = start - 600*multiple;
	go(value);
	showCurrentThumbsandTags();
}
//自动播放
function autoplay() {
	ap_time = setInterval(next_pic, 4000, 4);
}
// 各种事件
showCurrentThumbsandTags();
autoplay();
prev[0].onclick = function() {
	if(flag == 0) prev_pic(4);
}
next[0].onclick = function() {
	if(flag == 0) next_pic(4);
}
container.onmouseover = function() {
	clearInterval(ap_time);
}
container.onmouseout = function() {
	autoplay();
}
thumb_bkg.onmouseover = function() {
	clearInterval(ap_time);
}
thumb_bkg.onmouseout = function() {
	autoplay();
}
for (var i = 0; i < tags.length; i++) {
	(function(i){
		tags[i].onclick = function() {
			var distance = (i+1) - index;
			var multiple = Math.abs(distance);
			if(distance > 0) {
				var value = 4*multiple;
				if(flag == 0) {
					adj_next_pic(value);
				}
			}
			else if(distance < 0) {
				var value = 4*multiple;
				if(flag == 0) {
					adj_prev_pic(value);
				}
			}
			showCurrentThumbsandTags();
		}
		thumbs[i].onclick = function() {
			var distance = (i+1) - index;
			var multiple = Math.abs(distance);
			if(distance > 0) {
				var value = 4*multiple;
				if(flag == 0) {
					adj_next_pic(value);
				}
			}
			else if(distance < 0) {
				var value = 4*multiple;
				if(flag == 0) {
					adj_prev_pic(value);
				}
			}
			showCurrentThumbsandTags();
		}
	})(i)
}

只有一个玄学bug,就是在他播放的过程中,如果不切换网页,轮播图永远不会乱。但是如果在某些情况下(60%)打开别的网页后再返回该网页,轮播图就会乱,控制台调试表明参数会产生误差,至于为什么打开网页参数会乱,这超出我的认知范围,如果有大佬知道,麻烦指一下原因,感激不尽。。

 

最后惯例上素材包:

click here

 

建议欢迎指出,emmm,至于前面的算法博客。。好多忘了,如果有机会复习就一一解答。。求轻喷。。

你可能感兴趣的:(前后端相关学习,轮播图,javascript,html,css,滑动)