P127. 定时器简介
这节课将实现制作一个简易的定时器。
setInterval()
- 这个方法可以对函数定时调用,将一个函数每隔一段时间执行一次。
- 参数:
- 回调函数,该函数会每隔一段时间执行一次。
- 每次调用间隔的时间,单位为毫秒。
- 有一个返回值:
- 返回一个Number类型的数据。
- 这个数字用来作为定时器的唯一标识,方便我们用clearInterval()关闭定时器。
clearInterval()
- 可以用来关闭一个定时器。
- 方法中需要一个定时器的标识符作为参数。
下面就可以实现定时器的功能了。
...
<script type="text/javascript">
window.onload = function(){
var content = document.querySelector("#content");
var num = 1;
//设置定时器
var timer = setInterval(function(){
content.innerHTML = num++;
if (num == 100) { clearInterval(timer); } //当num为100时结束定时器
},50);
}
</script>
...
<body>
<h2 id="content">1</h2>
</body>
...
P128. 切换图片练习
本节课将实现一个自动切换图片的练习。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var img = document.querySelector("#img1");
var imgArr = ["../images/01.jpg","../images/02.jpg","../images/03.jpg","../images/04.jpg"]
var index = 0;
setInterval(function(){
index++;
//下面这行代码和18行代码同样作用,却更简洁。
//因为当索引超过数组的时候需要重置索引,4%4刚好又为0
index = index % imgArr.length;
// if (index >= imgArr.length){ index = 0; }
img.src = imgArr[index];
},500);
};
</script>
</head>
<body>
<img src="../images/01.jpg" id="img1" width="300px" height="300px"/>
</body>
</html>
我们还希望可以为我们的网页添加两个按钮,我们点击开始的时候开始,点击停止的时候停止。这其实也很简单,为我们的定时器绑定单击响应函数即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var img = document.querySelector("#img1");
var imgArr = ["../images/01.jpg","../images/02.jpg","../images/03.jpg","../images/04.jpg"]
var index = 0;
var start = document.querySelector("#start");
var stop = document.querySelector("#stop");
var timer; //这里的timer一定要是全局变量,不然stop()读取不到timer。
start.onclick = function(){
//一定要在开始位置清空一次定时器,不然当你多次点击定时器时
//会重复执行多个定时器,导致图片切换速度变快。
clearInterval(timer);
timer = setInterval(function(){
index++;
index = index % imgArr.length;
img.src = imgArr[index];
},500);
};
stop.onclick = function(){
clearInterval(timer);
}
};
</script>
</head>
<body>
<img src="../images/01.jpg" id="img1" width="300px" height="300px"/>
</br></br>
<button id="start">开始</button> //点击开始开始定时器
<button id="stop">停止</button> //点击停止关闭定时器
</body>
</html>
好的,那么做到这里,我们的程序就暂时做完了,当然,现在程序还不够完善,如果有能力的朋友可以想办法再改进改进这些代码。
还记得前面学习事件的时候(P123)使用键盘移动div那一课吗?我们最后面制作出的程序发现,由于因为键盘为了防误操作设计,第一次移动div总是有停顿感,我们现在学了定时器,有什么方法可以改进呢?
P129. 改进键盘移动div练习
我们前面制作的代码,我们发现,移动方向是没有问题的,有问题的是移动的速度,我们发现我们的控制方向和控制速度都是在onkeydown事件中完成的,这是不好的,就像我们骑自行车一样,手用来管方向,而脚用来管速度。
所以我们可以开启一个定时器,来控制div移动的速度。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script type="text/javascript">
window.onload = function(){
var speed = 20; //定义初始速度
dir = 0; //初始化方向为0
var box1 = document.querySelector("#box1");
setInterval(function(){
switch(dir){
case 38:
box1.style.top = box1.offsetTop - speed + "px";
break;
case 40:
box1.style.top = box1.offsetTop + speed + "px";
break;
case 37:
box1.style.left = box1.offsetLeft - speed + "px";
break;
case 39:
box1.style.left = box1.offsetLeft + speed + "px";
break;
}
},10);
document.onkeydown = function(event){
//上:38 下:40 左:37 右:39
if (event.ctrlKey){
speed = 50; //按ctrl加速。
}
else{
speed = 10;
}
// dir等于键盘的上下左右按键
dir = event.keyCode;
}
document.onkeyup = function(){
// 松手需要把dir设置为0,这样才会停止switch事件
dir = 0;
}
}
</script>
</head>
<body>
<div id="box1"></div>
</body>
</html>
P130. 延时调用
延时调用:
- 使用setTimeout()方法。
- 延时调用的函数不马上执行,而是隔一段时间后执行,而且只执行一次。
- 延时调用和定时调用的区别,定时调用会执行多次,延时调用只执行一次。
- 语法:setTimeout(回调函数,延时时间)
关闭延时调用:
- 使用clearTimeout()方法。
- 和关闭定时器方法一样使用。
- 语法:clearTimeout(延时器名字)
使用方法如:
var num = 1;
//设置延时器
var timer = setTimeout(function(){
console.log(num++);
},3000)
//关闭延时器
clearInterval(timer);
P131. 定时器的应用(一)
本节课我们利用定时器制作一个点击按钮向右移动div的效果,并且div移动到页面800像素的位置会自动停下来。
代码清单:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left:0;
}
#box2{
width: 0px;
border-right: 1px solid black;
height: 1000px;
background-color: black;
position: absolute;
top: 0px;
left: 800px;
}
</style>
<script type="text/javascript">
window.onload = function(){
var btn = document.querySelector("#btn");
var box1 = document.querySelector("#box1");
var timer;
//点击按钮以后,box向右移动
btn.onclick = function(){
//每次点击按钮重置定时器
clearInterval(timer);
//开启定时器,执行移动效果
timer = setInterval(function(){
//利用parseInt()方法,过滤掉字符串中的px字符,也可以使用正则表达式
var oldLeft = parseInt(getStyle(box1,"left"));
var newLeft = oldLeft + 12;
if (newLeft > 800){
newLeft = 800;
}
box1.style.left = newLeft + "px";
if (newLeft === 800){
//达到目标线,停止定时器
clearInterval(timer);
}
},20);
};
function getStyle(obj,str){
//利用或运算的优势,style等于网页中有的那个方法。
style = obj.currentStyle || window.getComputedStyle(obj,null);
return style[str];
}
};
</script>
</head>
<body>
<button id="btn">点击按钮向右移动div</button>
</br></br>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
P132. 定时器的应用(二)
上节课的代码虽然已经可以实现功能,但是还不够完善,这节课我们将尝试添加一个向左移动div的按钮,并将代码封装到一个函数中。
函数参数提示:
- obj:需要执行移动效果的对象。
- target:执行动画的目标位置。
- speed:移动的速度(正数向右移动,负数向左移动)
代码清单:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left:0;
}
#box2{
width: 0px;
border-right: 1px solid black;
height: 1000px;
background-color: black;
position: absolute;
top: 0px;
left: 800px;
}
</style>
<script type="text/javascript">
window.onload = function(){
var btn1 = document.querySelector("#btn1");
var btn2 = document.querySelector("#btn2");
var box1 = document.querySelector("#box1");
btn1.onclick = function(){
move(box1,800,10);
};
btn2.onclick = function(){
move(box1,0,10);
};
};
function getStyle(obj,str){
//利用或运算的优势,style等于网页中有的那个方法。
style = obj.currentStyle || window.getComputedStyle(obj,null);
return style[str];
}
var timer;
function move(obj,target,speed){
clearInterval(timer);
//获取元素当前的位置
var current = parseInt(getStyle(obj,"left"));
//判断速度的正负值,如果0像800移动,speed为正,如果800向0移动,speed为负
if (current > target){
speed = -speed;
}
timer = setInterval(function(){
var oldLeft = parseInt(getStyle(obj,"left"));
var newLeft = oldLeft + speed;
//利用speed正负判断方向
//向右移动时,需要判断newLeft是否大于target
//向左移动时,需要判断newLeft是否小于target
if ((speed < 0 && newLeft < target) || (speed > 0 && newLeft > target)){
newLeft = target;
}
obj.style.left = newLeft + "px";
if (newLeft === target){
//达到目标线,停止定时器
clearInterval(timer);
}
},20);
}
</script>
</head>
<body>
<button id="btn1">点击按钮向右移动div</button>
<button id="btn2">点击按钮向左移动div</button>
</br></br>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
P133. 定时器的应用(三)
上面已经基本完成了我们的需求,这节课我们将增加一些新的功能以及解决一些BUG。 BUG: 原来的代码,当我们想控制多个box时,由于定时器timer是唯一的,所以我们控制别的box会不小心关闭另一个box的进程。 新功能:
- 我们可以不单单只能向左向右移动,可以向上向下,变宽变窄,使得box更多样化。
- 增加一个回调函数,在动画执行完毕后调用,也可以不调用此参数。
解决BUG的方法:
我们不要再将timer设置为全局变量了,应该设置为box的一个方法,当我们点击按钮时,对应box对象的timer才开启定时器,关闭同理。
增加新功能的方法:
- 增加一个attr参数,里面填入left、top、width等操作,然后函数也会执行对应的操作。
- 增加回调函数可以使我们的程序更加灵活,如果我们想在动画执行完毕后,弹出一些提示框,可以利用回调函数,或者如果动画执行完毕后想再次执行动画,还可以使用回调函数。
最后,为了我们代码的可复制性,我们可以为我们的js和css代码封装到一个新的文件中,这样我们换一个文件还可以使用这些代码。
代码清单:
//css部分
*{
padding: 0;
margin: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left:0;
}
#box3{
width: 0px;
border-right: 1px solid black;
height: 1000px;
background-color: black;
position: absolute;
top: 0px;
left: 800px;
}
#box2{
width: 100px;
height: 100px;
background-color:teal;
position: absolute;
top: 200px;
left: 0;
}
//js部分
function getStyle(obj,str){
//利用或运算的优势,style等于网页中有的那个方法。
style = obj.currentStyle || window.getComputedStyle(obj,null);
return style[str];
}
//添加attr和回调函数
function move(obj,attr,target,speed,callback){
clearInterval(obj.timer);
//获取元素当前的位置
var current = parseInt(getStyle(obj,attr));
//判断速度的正负值,如果0像800移动,speed为正,如果800向0移动,speed为负
if (current > target){
speed = -speed;
}
obj.timer = setInterval(function(){
//只要获得回调函数中的值就好
var oldLeft = parseInt(getStyle(obj,attr));
var newLeft = oldLeft + speed;
//利用speed正负判断方向
//向右移动时,需要判断newLeft是否大于target
//向左移动时,需要判断newLeft是否小于target
if ((speed < 0 && newLeft < target) || (speed > 0 && newLeft > target)){
newLeft = target;
}
//这里要改成[]而不能使用.操作
obj.style[attr] = newLeft + "px";
if (newLeft === target){
//达到目标线,停止定时器
clearInterval(obj.timer)
//利用与操作符的作用,有传回调函数就调用
callback && callback();
}
},20);
}
<!--html部分-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="./style.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="./tools.js"></script>
<script type="text/javascript">
//本文件中的js代码只需要负责调用js文件中的函数就好。
window.onload = function(){
var btn1 = document.querySelector("#btn1");
var btn2 = document.querySelector("#btn2");
var btn3 = document.querySelector("#btn3");
var btn4 = document.querySelector("#btn4");
var box1 = document.querySelector("#box1");
var box2 = document.querySelector("#box2");
btn1.onclick = function(){
move(box1,"left",800,30);
};
btn2.onclick = function(){
move(box1,"left",0,10);
};
btn3.onclick = function(){
move(box2,"width",800,10,function(){
move(box2,"width",100,10);
});
}
btn4.onclick = function(){
move(box2,"width",100,10);
}
};
</script>
</head>
<body>
<button id="btn1" style="width: 100px;">box1向右移动</button>
<button id="btn2" style="width: 100px;">box1向左移动</button>
<button id="btn3" style="width: 100px;">box2向右移动</button>
<button id="btn4" style="width: 100px;">box2向左移动</button>
</br></br>
<div id="box1"></div>
<div id="box3"></div>
<div id="box2"></div>
</body>
</html>
P134. 制作轮播图
P134—P137都是制作轮播图的课程,此处就不再过多的写笔记,仅展示代码部分,有需求请看原视频。
//css部分
*{
margin: 0;
padding: 0;
}
#outer{
width: 620px;
height: 400px;
margin: 50px auto;
background-color: rgb(122, 226, 240);
padding: 10px 0;
position: relative;
overflow: hidden;
}
#imgList{
list-style: none;
position: absolute;
left: 0px;
}
#imgList li{
float: left;
margin: 0 10px;
}
#navDiv{
position: absolute;
bottom: 20px;
}
#navDiv a{
float: left;
width: 15px;
height: 15px;
background-color: rgb(255, 99, 71);
opacity: 0.7;
transition: 50ms;
/*透明度兼容IE8*/
filter: alpha(opacity=50);
margin: 0 5px;
}
#navDiv a:hover{
background-color: rgb(112, 170, 218);
}
//js部分
window.onload = function(){
let imgList = document.querySelector("#imgList");
let imgArr = document.querySelectorAll("img");
imgList.style.width = 620*imgArr.length + "px";
//设置导航按钮居中
//获取navDIv
let navDiv = document.querySelector("#navDiv");
let outer = document.querySelector("#outer");
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";
//获取所有a标签
let allA = document.querySelectorAll("a");
//设置a标签索引
index = 0;
//设置默认选中的颜色
allA[index].style.backgroundColor = "rgb(112, 170, 218)";
for (let i = 0;i<allA.length;i++){
//为每一个超链接都添加一个编号
allA[i].num = i;
allA[i].onclick = function(){
//清空定时器
clearInterval(timer);
index = this.num;
//设置标签变色
setA();
move(imgList,"left", -620*index ,70,function(){
//由于前面关闭了定时器,这边要再开启
autoChange();
});
}
}
//开启自动切换图片
autoChange();
//设置索引切换样式
function setA(){
/*我们采用一种偷梁换柱的方法,因为最后一张图片等于第一张图片,
所以将最后一张图片突然变成第一张图片,由于改变太快,肉眼是察觉不到的。
*/
if (index >= imgArr.length - 1){
index = 0;
imgList.style.left = "0px";
}
//将所有a标签恢复默认颜色
for (let i = 0;i<allA.length;i++){
allA[i].style.backgroundColor = "";
}
allA[index].style.backgroundColor = "rgb(112, 170, 218)";
}
var timer;
//自动切换图片函数
function autoChange(){
timer = setInterval(function(){
//索引自增
index++;
index %= imgArr.length;
move(imgList,"left", -620*index ,70,function(){
//利用回调函数修改底部索引
setA();
});
},3000);
}
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!--引用js文件和css文件-->
<link type="text/css" rel="stylesheet" href="style.css"/>
//tools文件就是上节课"定时器的应用(三)"中的js部分,script文件为上方js代码
<script type="text/javascript" src="tools.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="./img/1.jpg" width="600px" height="400px"/></li>
<li><img src="./img/2.jpg" width="600px" height="400px"/></li>
<li><img src="./img/3.jpg" width="600px" height="400px"/></li>
<li><img src="./img/4.jpg" width="600px" height="400px"/></li>
<li><img src="./img/5.jpg" width="600px" height="400px"/></li>
<li><img src="./img/1.jpg" width="600px" height="400px"/></li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</body>
</html>
P137. 类的操作
我们假设有这么一段代码
//css部分
<style type="text/css">
.b1{
width: 100px;
height: 100px;
background-color: red;
}
</style>
...
//html部分
<body>
<button id="btn1">点击按钮修改box样式</button>
</br></br>
<div id="box" class="b1"></div>
</body>
我们现在想在js中设置点击按钮增加box的长和宽,那我们可以会这么做。
<script type="text/javascript">
window.onload = function(){
//获取box
var box = document.querySelector("#box");
//获取btn1
var btn1 = document.querySelector("#btn1");
btn1.onclick = function(){
box.style.width = "200px";
box.style.height = "200px";
}
};
</script>
这种方法是正确的,我们只需要调用对象的style属性即可,但是这种方法也有个不好的缺陷,那就是如果我们需求变化了,比如还要改变颜色,还要增加边框…这时,我们单纯的写一条条js代码就过于繁杂,并且不利于修改。
同时通过style属性来修改元素时,每修改一个样式,浏览器就需要重新渲染一次页面,这样执行的性能是比较差的。
我们希望,只需要一行代码,可以修改多个样式,我们可以通过修改类名的方式来实现这点。
//css增加新的样式newb1
.newb1{
width: 200px;
height: 200px;
background-color: blue;
}
//js部分
<script type="text/javascript">
window.onload = function(){
//获取box
var box = document.querySelector("#box");
//获取btn1
var btn1 = document.querySelector("#btn1");
btn1.onclick = function(){
box.className = "newb1"; //这里只需要修改类名即可
}
};
</script>
//html部分不变
但是这里还有个问题,那就是如果我们只想修改高度,不想修改长度,然后我们把newb1样式中的宽度样式删了会发现,这时的宽度居然会继承父元素的宽度。这是因为我们是直接修改的类名,而替换的类中要是没有宽度这个样式,会自动继承父元素的宽度,那么我们应该怎么修改呢?
//假设我们的替换的css不需要修改宽度
.newb1{
height: 200px;
background-color: blue;
}
//单击响应函数修改为
btn1.onclick = function(){
box.className += " newb1"; //我们采用字符串拼串的方式,这里需要在前面加个空格
}
上面这个写完了程序是可以正常运行了,表面看上去好像也没有问题,但是我们点击按钮后打开网页的审查元素一看,完了,随着我们点击按钮的次数增多,标签中的类名也会越变越多,这样虽然对我们的程序没什么影响,但是未免不太美观。
所以我们可以写一个函数,判断标签中是否已经有我们想要添加的类名,有我们就不添加了,还记得正则表达式吗?我们可以是有正则表达式来完成这个问题。
<script type="text/javascript">
window.onload = function(){
//获取box
var box = document.querySelector("#box");
//获取btn1
var btn1 = document.querySelector("#btn1");
btn1.onclick = function(){
//我们设置一个专门添加类名的函数,第一个参数为元素对象,第二个参数为类名
addClass(box,"newb1");
}
};
function addClass(obj,str){
//进行判断,如果有那个类了,就不要再添加了
if (!hasClass(obj,str)){
obj.className += " " + str;
}
}
function hasClass(obj,str){
//需要检测单词边界
var reg = new RegExp("\\b" + str + "\\b","g");
//利用三目运算符简化代码,正则检测到了就返回true,没检测到返回false
return reg.test(obj.className) ? true : false;
}
</script>
运用上面的知识,我们可以再为我们的网页添加一个删除类的函数。
function removeClass(obj,str){
var reg = new RegExp(" \\b" + str + "\\b","g");
obj.className = obj.className.replace(reg,"");
}
最后,我们把前面的函数整合一下,创建一个toggleClass函数,这个函数可以切换我们的类,如果元素中具有该类,则删除,反之,则添加。
function toggleClass(obj,str){
//利用hasClass函数判断
if (hasClass(obj,str)){
removeClass(obj,str);
}
else{
addClass(obj,str);
}
}
如果我们把这个函数添加到我们按钮的单击响应函数当中,我们就可以实现有类的时候删除类,无类的时候添加类。
最终代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.b1{
width: 100px;
height: 100px;
background-color: red;
}
.newb1{
height: 200px;
background-color: blue;
}
.newb2{
width: 400px;
height: 200px;
background-color: blue;
}
</style>
<script type="text/javascript">
window.onload = function(){
//获取box
var box = document.querySelector("#box");
//获取btn1
var btn1 = document.querySelector("#btn1");
btn1.onclick = function(){
//调用函数
toggleClass(box,"newb2")
}
};
//添加类
function addClass(obj,str){
if (!hasClass(obj,str)){
obj.className += " " + str;
}
}
//判断类是否存在
function hasClass(obj,str){
//需要检测单词边界
var reg = new RegExp("\\b" + str + "\\b","g");
//利用三目运算符简化代码,正则检测到了就返回true,没检测到返回false
return reg.test(obj.className) ? true : false;
}
//删除类
function removeClass(obj,str){
var reg = new RegExp(" \\b" + str + "\\b","g");
obj.className = obj.className.replace(reg,"");
}
//切换类
function toggleClass(obj,str){
if (hasClass(obj,str)){
removeClass(obj,str);
}
else{
addClass(obj,str);
}
}
</script>
</head>
<body>
<button id="btn1">点击按钮修改box样式</button>
</br></br>
<div id="box" class="b1 newb2 newb1"></div>
</body>
</html>
P138. 二级菜单
P138-P139来尝试实现一个二级菜单的网页,由于我这没有老师css和HTMl的源码,这两部分由我依据模样大概制作完毕,仅作为参考。
//CSS部分
*{
padding: 0;
margin: 0;
list-style-type: none;
}
a,img{
border: 0;
text-decoration: none;
}
body{
font: 12px/180% Arial, Helvetica,sans-serif,"新宋体";
}
#my_menu{
width: 200px;
text-align: center;
background-color: blanchedalmond;
margin: 50px auto;
cursor: pointer;
user-select: none;
border-radius: 10px;
padding-bottom: 10px;
overflow: hidden;
}
.collapsed{
width: 100%;
height: 25px;
}
.menuSpan{
display: block;
line-height: 25px;
background-color: rgb(95, 216, 166);
}
a{
display: block;
color: rgb(16, 39, 16);
height: 30px;
line-height: 30px;
transition: 70ms all;
}
a:hover{
background-color: brown;
color: white;
}
//tools工具包
function getStyle(obj,str){
//利用或运算的优势,style等于网页中有的那个方法。
style = obj.currentStyle || window.getComputedStyle(obj,null);
return style[str];
}
//imgList,"left", -620*index ,70
function move(obj,attr,target,speed,callback){
clearInterval(obj.timer);
//获取元素当前的位置
var current = parseInt(getStyle(obj,attr));
//如果你当前位置大于你目标位置,speed为负,如果你当前位置小于目标位置,speed为正
if (current > target){
speed = -speed;
}
//开启定时器
obj.timer = setInterval(function(){
var oldLeft = parseInt(getStyle(obj,attr));
var newLeft = oldLeft + speed;
//利用speed正负判断方向
//向右移动时,需要判断newLeft是否大于target
//向左移动时,需要判断newLeft是否小于target
if ((speed < 0 && newLeft < target) || (speed > 0 && newLeft > target)){
newLeft = target;
}
obj.style[attr] = newLeft + "px";
if (newLeft === target){
//达到目标线,停止定时器
clearInterval(obj.timer)
//调用回调函数
callback && callback();
}
},20);
}
function addClass(obj,str){
if (!hasClass(obj,str)){
obj.className += " " + str;
}
}
function hasClass(obj,str){
//需要检测单词边界
var reg = new RegExp("\\b" + str + "\\b","g");
//利用三目运算符简化代码,正则检测到了就返回true,没检测到返回false
return reg.test(obj.className) ? true : false;
}
function removeClass(obj,str){
if (obj.className = ""){
var reg = new RegExp("\\b" + str + "\\b","g");
}else{
var reg = new RegExp(" \\b" + str + "\\b","g");
}
obj.className = obj.className.replace(reg,"");
}
function toggleClass(obj,str){
if (hasClass(obj,str)){
removeClass(obj,str);
}
else{
addClass(obj,str);
}
}
<!--html部分-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!--引入外部的css和js文件,tools文件为上方代码-->
<link type="text/css" rel="stylesheet" href="./css/style.css"/>
<script type="text/javascript" src="./js/tools.js"></script>
<script type="text/javascript">
window.onload = function(){
/*每一个菜单都是一个div
* 当div具有collapsed这个类时,div就是折叠状态
* 反之就是展开状态
*/
//获取所有类名为menuSpan的标签
var menuSpan = document.querySelectorAll(".menuSpan");
//定义一个变量,保存当前以打开的菜单
var openDiv = menuSpan[0].parentNode;
for (var i = 0;i<menuSpan.length;i++){
menuSpan[i].onclick = function(){
/* alert("hh"); */
var parentDiv = this.parentNode;
toggleMenu(parentDiv);
//判断parentDiv和openDiv是否相等
if (parentDiv != openDiv && !hasClass(openDiv,"collapsed")){
//关闭当前打开的菜单
toggleMenu(openDiv);
}
openDiv = parentDiv;
}
}
function toggleMenu(obj){
var begin = obj.offsetHeight;
//切换菜单的展开与折叠
toggleClass(obj,"collapsed");
var end = obj.offsetHeight;
//执行动画,从begin向end过渡
obj.style.height = begin + "px";
move(obj,"height",end,10,function(){
obj.style.height = ""
});
}
};
</script>
</head>
<body>
<div id="my_menu" class="sdmenu">
<div style="overflow: hidden;margin: 3px 0;">
<span class="menuSpan">在线工具</span>
<a href="#">图像优化</a>
<a href="#">图标生成器</a>
<a href="#">邮件</a>
<a href="#">password密码</a>
<a href="#">地图图像</a>
<a href="#">按钮生成器</a>
</div>
<!--collapsed意为折叠-->
<div class="collapsed" style="overflow: hidden;margin: 3px 0;">
<span class="menuSpan">支持我们</span>
<a href="#">推荐我们</a>
<a href="#">关心我们</a>
<a href="#">了解我们</a>
</div>
<div class="collapsed" style="overflow: hidden;margin: 3px 0;">
<span class="menuSpan">合作伙伴</span>
<a href="#">腾讯视频</a>
<a href="#">阿里巴巴集团</a>
<a href="#">网易邮箱</a>
</div>
<div class="collapsed" style="overflow: hidden;margin: 3px 0;">
<span class="menuSpan">测试电流</span>
<a href="#">what you name?</a>
<a href="#">what you name?</a>
<a href="#">what you name?</a>
<a href="#">what you name?</a>
<a href="#">what you name?</a>
</div>
</div>
</body>
</html>
P140. JSON
我们了来创建一个对象
var obj = {name:"张三",age:15,gender:"男"};
console.log(obj.name);
我们输出这个对象,可以发现是没有任何问题的,但是未来我们如果去做项目,很有可能会有一个需求,就是需要和后台服务器去做交互,毕竟一个网站是由前端,还需要后台服务器对我们的网页提供支持。
可是我们要和服务器做交互,但是服务器用的语言可以JAVA,C++…并不是使用JavaScript写的,可是我们现在有个对象,我们需要传给服务器,可是JS中的对象,只有JS认识,服务器传过来的对象只有服务器认识。
那我们想想,有什么是JS和其他任何语言都认识的东西呢,比如整数、布尔值、字符串…这些类型是任何语言都有的东西,那我们转换成什么好呢,整数?太麻烦了;布尔值?true和false无法表达我们需要传达的那么多信息;字符串呢?字符串就刚刚好,字符串任何语言都认识,甚至是我们自己看,都能看出表达的意思。
var obj = '{"name":"张三","age":15,"gender":"男"}';
//将对象转换成一个字符串
console.log(typeof(obj));
概念
JSON -> JavaScript Object Notation (JS对象表示法)
JSON就是一个特殊格式的字符串,这个字符串可以被任意语言所识别,并且可以转换成任意语言中的对象,JSON在开发中主要用于数据的交互
JSON规则
- JSON和JS对象格式一样,只不过JSON字符串中的属性名必须加双引号!!其他和JS语法一致。
- JS分类
- 对象{}
- 数组[]
- JSON中允许的值
- 1.字符串
- 2.数值
- 3.布尔值
- 4.null
- 5.对象(不包括函数对象)
- 6.数组
如上方所示,修改为字符串之后,我们会发现我们也无法调用JSON字符串中的对象了,所以在JS中,为我们提供了一个工具类,就叫JSON,这个对象可以帮我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON。
JSON -> JS对象
JSON.parse()方法
JSON.stringify()方法
这个函数可以用来执行一段字符串形式的代码,并将执行结果返回。
如果使用eval()执行的字符串中含有{},它会将{}当成一个代码块,如果不希望被当成代码块来解析,需要在字符串前后加上()
var test = '{"name":"刘备","age":18}';
var obj = eval("(" + test + ")");
console.log(obj.name);
eval()这个函数的功能很强大,可以直接执行一串字符串中的JS代码,但是在开发中不建议使用,首先它的执行性能较差,其次它还具有安全隐患。
实际中兼容IE7的情况已经很少了,所以我们不推荐用这个方法。