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刚好又为0index = 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; //初始化方向为0var 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 右:39if (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是否小于targetif ((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是否小于targetif ((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";//设置导航按钮居中//获取navDIvlet 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(){//获取boxvar box = document.querySelector("#box");//获取btn1var 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(){//获取boxvar box = document.querySelector("#box");//获取btn1var 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(){//获取boxvar box = document.querySelector("#box");//获取btn1var 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,没检测到返回falsereturn 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(){//获取boxvar box = document.querySelector("#box");//获取btn1var 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,没检测到返回falsereturn 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 ,70function 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是否小于targetif ((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,没检测到返回falsereturn 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的情况已经很少了,所以我们不推荐用这个方法。
