JS部分学习
今天学习做了时钟,无限大图滚动,banner(导航的点击滑动)图,碰壁反弹的代码实现。
01闭包
闭包:是指有权访问函数作用域内变量的函数。可以简单的理解为函数内的函数是闭包,也就是函数内可以使用函数外定义的变量。在函数的声明处向函数的外部可以找到所有声明的全局变量,在函数的内部能访问到所有变量的最终值。
闭包的特点 :
1. 在函数内部声明的变量,外部是没有办法直接访问的,他保护了函数内部变量不受外部变量污染。可以使用闭包函数访问局部变量。
2. 在闭包函数中,使用当前作用域的变量,在局部变量的作用域内,不能立即销毁,依然存在于内存当中。
如下代码case1:
function aa() {
var m = 10;
function son() {
console.log(m); //son是函数aa的闭包 son可以访问外部所有变量
};
son();
}
aa(); //要执行闭包,首先要执行aa()
case2:
function fun1() {
var a = 10;
return function() { //先返回的是一个函数
a++;
console.log(a);
}
}
fun1()(); //返回11
fun1()(); //返回11,函数外部并不能改变函数内部的变量,因此返回的值还是11
var fun = fun1(); //用外部写的方法可以在外部传入想传入的参数 逃不出fun1的作用域,闭包只能访问fun1 里面的变量
fun(); //返回值为11
fun(); //返回值为12
fun(); //返回值为13,以上的fun变量是属于window的,将函数赋给全局变量,这样就相当于可以改变函数内部的值了
闭包并没有销毁,因此很占内存,使用时要清除一下。
case3:
function fun2() {
var a = 90;
return function(n) {
a = n;
console.log(a); //返回300
}
}
var fu =fun2();
fu(300); //相当于在fun2里传入参数300,参数放在闭包里,不受影响,闭包函数只能访问变量的最终值!!!
重要应用实例,点击对应的li,对应li执行相应的函数:
var arr = document.getElementsByTagName('li'); //先获取body中的li
function liTest() {
for (var i = 0; i<arr.length;i++) {
arr[i].onclick = function() {
alert(i); //点击对应li,弹出ul中li对应的下标
}
}
}
liTest();
注意:
由于闭包函数会携带它所在的函数作用域,因此会比其他函数多占用内存空间,过度的使用闭包,会导致内存占用过多。因此给出的建议是(闭包能不用就不用),如果必要时(例如需要绑定事件)。js就是一个大的闭包,可以多定义函数。
02时钟的页面整体实现
下面的背景图部分是加的图片
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>时钟</title>
<style type="text/css"> //css样式
* {
margin: 0;
padding: 0;
}
ul,li {
list-style-type: none;
}
/* 表盘 */
.pan {
width: 600px;
height: 600px;
background: radial-gradient(#666 0%,#f0f0f0 100%);
margin: 50px auto;
border-radius: 50%;
overflow: hidden;
position: relative;
}
.nei {
width: 560px;
height: 560px;
background: url(./imgs/tupian2.jpg) no-repeat center center;
background-size: cover;
border-radius: 50%;
margin: 20px;
position: relative;
}
.nei li {
width: 10px;
height: 30px;
background: #aaa;
display: block;
position: absolute;
left: 275px;
top: 0;
transform-origin: 5px 280px;
}
.nei li span {
font-size: 40px;
display: block;
width: 60px;
margin: 40px 0 0 -25px;
color: #f00;
text-align: center;
}
/* 表针 */
.zhen {
width: 600px;
height: 600px;
position: absolute;
left: 0;
top: 0;
border-radius: 50%;
z-index: 10;
}
.zhen * {
position: absolute;
background: #fff;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
left: 275px;
top: 275px;
}
#hour {
width: 20px;
height: 140px;
left: 290px;
top: 195px;
transform-origin: 10px 105px;
}
#min {
width: 10px;
height: 200px;
left: 295px;
top: 145px;
transform-origin: 5px 155px;
}
#sec {
width: 4px;
height: 230px;
left: 298px;
top: 125px;
transform-origin: 2px 175px;
}
</style>
</head>
<body>
<div class="pan">
<ul class="nei" id="list">
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
<li><span>6</span></li>
<li><span>7</span></li>
<li><span>8</span></li>
<li><span>9</span></li>
<li><span>10</span></li>
<li><span>11</span></li>
<li><span>12</span></li>
</ul>
<!-- 表针 -->
<div class="zhen">
<!-- 中间圆点 -->
<span class="circle"></span>
<!-- 时针 -->
<span id="hour"></span>
<!-- 分针 -->
<span id="min"></span>
<!-- 秒针 -->
<span id="sec"></span>
</div>
</div>
</body>
</html>
<script type="text/javascript">
var list = document.getElementById("list");
var lis = list.getElementsByTagName('li');
var spans = list.getElementsByTagName('span');
for (var i = 0; i < lis.length; i++){
lis[i].style.transform = 'rotate('+30*(i+1)+'deg)';
spans[i].style.transform = 'rotate('+(-30)*(i+1)+'deg)';
}
// 获取表针
var hour = document.getElementById("hour");
var min = document.getElementById("min");
var sec = document.getElementById("sec");
function showTime() {
//获取当前时间
var myDate = new Date();
// 时
var h = myDate.getHours();
// 分
var m = myDate.getMinutes();
// 秒
var s = myDate.getSeconds();
//设置表针旋转
// 秒
sec.style.transform = 'rotate('+s*6+'deg)';
// 分
min.style.transform = 'rotate('+(m*6+s/10)+'deg)';
// 时
hour.style.transform = 'rotate('+(h*30+m/2+s/120)+'deg)'
}
showTime();
setInterval(showTime,1000);
</script>
时钟的显示效果图:
03无限大图滚动
<!DOCTYPE html>
<html>
/*css样式在此不再示出*/
<body>
<div class="wp">
<ul id="list">
<li>
<img src="imgs/car.jpg" >
</li>
<li>
<img src="imgs/pu.jpg" >
</li>
<li>
<img src="imgs/tupian6.jpg" >
</li>
<li>
<img src="imgs/yu3.jpg" >
</li>
</ul>
</div>
</body>
</html>
<script type="text/javascript">
var list = document.getElementById("list");
var timmer; //计时器
var n = 0; //当前是第几张图
var x = 0; //元素#list移动的距离
var w = 1000; //一个li的宽度
// 扩充list内部的HTML结构
list.innerHTML += list.innerHTML;
var lis = list.getElementsByTagName('li');
//重置ul的宽度
list.style.width = w*lis.length+'px';
//获取临界值
var myWidth = -w*lis.length/2;
function move() {
list.style.transform = 'translateX('+x+'px)';
//边界控制
if (x%w == 0) {
setTimeout(function() {
x--;
},2000);
} else {
x--;
}
if (x<=myWidth) {
x=0;
}
}
timmer = setInterval(move,10)
</script>
04banner图
这里用的图片与上面无限大图一致,在body的wp里加上如下代码,实现四个小圆点。
<div id="circle">
<span class="on"></span>
<span></span>
<span></span>
<span></span>
</div>
js实现:
<script type="text/javascript">
var list = document.getElementById("list");
var circle = document.getElementById("circle");
var spans = circle.getElementsByTagName('span');
for (var i = 0; i <spans.length; i++) {
(function(i) {
spans[i].onclick = function() {
for(var j = 0; j<spans.length;j++) {
spans[j].className = '';
}
this.className = 'on';
list.style.transform = 'translateX('+(-i*1000)+'px)'
}
})(i);
}
</script>
05碰壁反弹
body部分给出一个框限制小球运动范围,里面装入一个小球。
<body>
<div id="wp">
<span id="ball"></span>
</div>
</body>
js实现:
<script type="text/javascript">
//声明随机函数
function rand(x,y) {
return Math.floor(Math.random()*(y-x+1))+x;
}
var wp = document.getElementById("wp");
var ball = document.getElementById("ball");
//随机小球的位置
var x = rand(0,950); //x轴每次移动的距离
var y = rand(0,750); //y轴每次移动的距离
ball.style.left = x+'px';
ball.style.top = y+'px';
//碰壁反弹本质是结合计时器实现小球移动
var spx = rand(1,10);
var spy = rand(1,10);
//设置移动方向
var xDir = true;
var yDir = true;
function move() {
//
if (xDir) {
x+=spx;
if(x>=950) {
x = 950;
xDir = false;
}
}else {
x-=spx;
if(x<=0) {
x = 0;
xDir = true;
}
}
if (yDir) {
y+=spy;
if(y>=750) {
y = 750;
yDir = false;
}
}else {
y-=spy;
if(y<=0) {
y=0;
yDir = true;
}
}
//设置x轴移动
ball.style.left = x+'px';
ball.style.top = y+'px';
//
}
setInterval(move,10);
</script>
效果如下: