自学前端的笔记:

首先是轮播图的思路:

①.用一个div(container)装需要展示的img,然后将这个大的div放进一个小的显示框(box)(即网页上可看的部分),对显示框设置超出部分隐藏。然后利用js或者css来改变container的left值,来实现图片轮播。

②.将所有图片设成绝对定位,装入一个div(container)容器中,通过改变图片的opacity和index或者display来实现图片轮播。

这里先介绍第一种。

html代码如下:

<div id="box"><!-- 显示框 -->
    	<div id="container"><!-- 容器 -->
    		<div id="img_a">
    			<img src="img/1.jpg">
    		</div>
    		<div id="img_b">
    			<img src="img/3.jpg">
    		</div>
    		<div id="img_c">
    			<img src="img/4.jpg">
    		</div>
    		<div id="img_d">
    			<img src="img/5.jpg">
    		</div>
    		 <div id="img_e">
    			<img src="img/6.jpg">
    		</div>
    	</div>

        <!-- 向左或向右滑动的按钮 -->
    	 <img src="img/new_l.png"  id="left" class="a">
        <img src="img/new_r.png" id="right" class="a">

        <!-- 移动到某张图片上的小圆点 -->
        <div id="xyd">
            <a href="#" class="a_b"></a>
            <a href="#" class="a_a"></a>
            <a href="#" class="a_a"></a>
            <a href="#" class="a_a"></a>
            <a href="#" class="a_a"></a>
        </div>
    	</div>	

css代码如下:

*{
	padding:0px;
	margin: 0px;
}
#box{
	width: 730px;
	overflow: hidden;/*隐藏超出部分*/
	position: relative;/*相对布局,让孩子container更容易控制*/
	height: 336px;
	margin:0 auto;
}

#container{
	position: absolute;/*绝对布局*/
	width: 3650px;
	height: 336px;
}
#container div{
	float: left;/*装载图片的盒子向左浮动,在container内为一横排*/
	width: 730px;

}

/*下面不是很重要,可随便调整*/
.a{
	position: absolute;
	 cursor:pointer;
}
#left{
	top: 150px;
	left: 5px;	
}
#right{
	top: 150px;
	right: 5px;	
}
#xyd{
	top: 280px;
	left: 350px;
	position: absolute;
}
.a_a{
	display: inline-block;
	margin: 5px;
    width: 5px;
    height: 5px;
    border-radius: 20px;
    border:1px solid #8E8E8E;
    background:#ADADAD;
}
.a_b{
	display: inline-block;
	margin: 5px;
    width: 10px;
    height: 10px;
    border-radius: 20px;
    border:1px solid #FFFFFF;
    background:#FFFFFF;
}

js代码如下:

首先一个move(控制container的移动,n为移动到第几张图片),c为container,xydArr为底部小圆点的元素集

通过定时器window.setInterval设置定时,并用num获取当前的位置,再将改变的参数传入move(),思路大致如此,而左右和小圆点,则是要加鼠标滑动到上面的事件,鼠标离开事件,鼠标点击事件。当鼠标移动到上面时,停止轮播,离开则恢复。

window.onload = function() {
	 
	// 轮播图部分
	 var c = get("container");//获取container
	 var num = (0-c.offsetLeft)/730;//获取当前num
	 var t1; //设置定时器变量

	 // 小圆点
	var xyd_c = get("xyd");//获取装小圆点的盒子
	var x = 0;//emmmm,定义当前清除的定时器编号
	var xydArr = xyd_c.getElementsByTagName('*');//获取小圆点数组

	
	 function timecount(){//设置定时器
		 	t1=window.setInterval(function(){
		 	var left = c.offsetLeft;
		 	num = (0-left)/730;
		 	// console.log(num);
		 	n = (num+1)%5
		 	move(n,c,xydArr);
		 	// c.style.left = (0-n)*730+"px";
		 	// console.log(c.offs	etLeft);
		 	// timecount();
		 },1000);
	}
	timecount();//运动定时器


	var divArr = c.getElementsByTagName('*');//获取装载图片的数组
	// 小圆点的三个事件
	for (var i = 0; i < xydArr.length; i++) {
		(function(i) {
			xydArr[i].onmouseover = function(){
				x = delet_time(x,t1); 
				move(i,c,xydArr);
				// this.className="a_b";
	    	}
	    	divArr[i].onmouseover = function(){
				x = delet_time(x,t1);
				// this.className="a_b";
	    	}
	    	xydArr[i].onmouseout = function(){
	    		x = delet_time(x,t1);
	    		timecount();
			 	// console.log(1);
			 	// console.log(1);
				// this.className="a_b";
	    	}
	    	divArr[i].onmouseout = function(){
	    		x = delet_time(x,t1);
				timecount();
				// this.className="a_b";
	    	}
	    	xydArr[i].onclick = function(){
				x = delet_time(x,t1);
				move(i,c,xydArr);
				// this.className="a_b";
	    	}
	    	
		})(i);
	}



	// 前一页,后一页
	var left = get("left");
	var right = get("right");
	//向左向右滑动按钮的事件
	left.onmouseover = function(){
		x = delet_time(x,t1);
	}
	left.οnmοuseοut=function(){
		x = delet_time(x,t1);
		window.setTimeout(function(){
		 	timecount();
		 	// console.log(1);
		 },2000);
	}
	left.οnclick=function(){
		x = delet_time(x,t1);
		var left = c.offsetLeft;
		num = (0-left)/730;
		// console.log(num);
		if (num==0) {
			n = 4;
		}
		else{
			n = (num-1)%5
		}
		
		// console.log(n);
		move(n,c,xydArr);
	}

	right.onmouseover = function(){
		x = delet_time(x,t1);
	}
	right.οnmοuseοut=function(){
		x = delet_time(x,t1);
		window.setTimeout(function(){
		 	timecount();
		 	// console.log(1);
		 },2000);
	}
	right.οnclick=function(){
		x = delet_time(x,t1);
		var left = c.offsetLeft;
		num = (0-left)/730;
		// console.log(num);
		n = (num+1)%5

		// console.log(n);
		move(n,c,xydArr);
	}


}

function get(Element){
	return document.getElementById(Element);
}

function move(n,c,xydArr) { //移动到第n张图片上
	for (var i = 0; i < xydArr.length; i++) {
		if (i==n) {
			xydArr[i].className="a_b";
		}
		else{
			xydArr[i].className="a_a";
		}
	};
	 c.style.left = (0-n)*730+"px";
}

function delet_time(x,t){ //清楚t的定时器
	var i = x+1;
	// console.log(x);
	// console.log(t);
	for (i = x+1; i <= t; i++) {
		// console.log("a:"+i);
		clearInterval(i);
		// console.log("b:"+i);
	};
	return --i;
		// delet_time(t);
}




由于是按照自己的思路打的js,没有经过整理,所以很凌乱。

问题:定时器清除不干净,导致一开始的时候由于定时器的标签编号过快,而使得有些定时器未清除,使得图片轮播越来越快。

定时器的性质:

var t1;//定时器的变量
function timecount(){//设置定时器
		 	t1=window.setInterval(function(){//第一次设置定时器,t1的编号为1,即t1=1
		 	var left = c.offsetLeft;
		 	num = (0-left)/730;
		 	// console.log(num);
		 	n = (num+1)%5
		 	move(n,c,xydArr);
		 	// c.style.left = (0-n)*730+"px";
		 	// console.log(c.offs	etLeft);
		 	// timecount();
		 },1000);
	}
	timecount();//t1=1
	timecount();//t1=2
	clearInterval(t1)//只能清除编号为2的定时器,而t1=1的残留
	clearInterval(1)//清除编号为1的定时器

所以常常会导致有一部分被跳过的定时器残留(暂时找不到原因),采用了暴力破除法,就是上面的delet_time方法,通过x记录当前已清除的定时器的最大编号,然后在下次需要清除时,清除编号[x+1,t]的定时器。

ps:window.onload 是页面加载完加载JavaScript。

总而言之,虽然代码有点乱,但最大的问题还是在定时器上。暴力破除虽然挺有效的,但总感觉不太对。


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐