导航栏

js学习(十六)-- 定时器的使用、类的操作、轮播图和二级菜单的实现、JSON

定时器方法

是BOM的window的方法

setInterval&clearInterval

  • 定时调用
  • 可以将一个函数每隔一段时间执行一次
    -参数:
  • 回调函数:该函数会每隔一段时间被调用一次
  • 每次调用间隔的时间,单位是毫秒
  • 返回值:
    返回一个NUmber类型的数据
    这个数字作为定时器的唯一标识
var num=1;
var timer = setInterval(function(){
      count.innerHTML = num++;
      if(num == 11){
            clearInterval(timer);
      }
},1000);

图片切换实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			window.onload = function() {

				/*
				 * 使图片可以自动切换
				 */

				//获取img标签
				var img1 = document.getElementById("img1");

				//创建一个数组来保存图片的路径
				var imgArr = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg", "img/5.jpg"];

				//创建一个变量,用来保存当前图片的索引
				var index = 0;

				//定义一个变量,用来保存定时器的标识
				var timer;

				//为btn01绑定一个单击响应函数
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function() {

					/*
					 * 目前,我们每点击一次按钮,就会开启一个定时器,
					 * 	点击多次就会开启多个定时器,这就导致图片的切换速度过快,
					 * 	并且我们只能关闭最后一次开启的定时器
					 */

					//在开启定时器之前,需要将当前元素上的其他定时器关闭
					clearInterval(timer);

					/*
					 * 开启一个定时器,来自动切换图片
					 */
					timer = setInterval(function() {
						//使索引自增
						index++;
						//判断索引是否超过最大索引
						/*if(index >= imgArr.length){
							//则将index设置为0
							index = 0;
						}*/
						index %= imgArr.length;
						//修改img1的src属性
						img1.src = imgArr[index];

					}, 1000);
				};

				//为btn02绑定一个单击响应函数
				var btn02 = document.getElementById("btn02");
				btn02.onclick = function() {
					//点击按钮以后,停止图片的自动切换,关闭定时器
					/*
					 * clearInterval()可以接收任意参数,
					 * 	如果参数是一个有效的定时器的标识,则停止对应的定时器
					 * 	如果参数不是一个有效的标识,则什么也不做
					 */
					clearInterval(timer);

				};


			};
		</script>
	</head>
	<body>

		<img id="img1" src="img/1.jpg" />
		<br /><br />
		<button id="btn01">开始</button>
		<button id="btn02">停止</button>
	</body>
</html>

setTimeout()&clearTimeout()

  • 延时调用
  • 调用一个函数但不马上执行,而是隔一段时间以后再执行
  • 也会返回一个时间标识用来关闭延时调用
var timer = setTimeout(function(){
      console.log(num++);
},3000);

claerTimeout(timer);

2.练习

2.1实现div的左右自动移动

点击按钮向左移动,移动到特定位置后停止,再点击向左移动,移动到left:0 px值时停止移动

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 100px;
				height: 100px;
				background-color: red;
				position: absolute;
			}
			
			
		</style>
		
		<script type="text/javascript">
			
			//使div可以根据不同的方向键向不同的方向移动
			/*
			 * 按左键,div向左移
			 * 按右键,div向右移
			 * 。。。
			 */
			window.onload = function(){
				
					
				//定义一个变量,来表示移动的速度
				var speed = 10;
				
				//创建一个变量表示方向
				//通过修改dir来影响移动的方向
				var dir = 0;
				
				//开启一个定时器,来控制div的移动
				setInterval(function(){
					/*
					 * 37 左
					 * 38 上
					 * 39 右
					 * 40 下
					 */
					switch(dir){
						case 37:
							//alert("向左"); left值减小
							box1.style.left = box1.offsetLeft - speed + "px";
							break;
						case 39:
							//alert("向右");
							box1.style.left = box1.offsetLeft + speed + "px";
							break;
						case 38:
							//alert("向上");
							box1.style.top = box1.offsetTop - speed + "px";
							break;
						case 40:
							//alert("向下");
							box1.style.top = box1.offsetTop + speed + "px";
							break;
					}
				},30);
				
				
				
				//为document绑定一个按键按下的事件
				document.onkeydown = function(event){
					event = event || window.event;
					
					//当用户按了ctrl以后,速度加快
					if(event.ctrlKey){
						speed = 500;
					}else{
						speed = 10;
					}				
					//使dir等于按键的值
					dir = event.keyCode;
				};			
				//当按键松开时,div不再移动
				document.onkeyup = function(){
					//设置方向为0
					dir = 0;
				};			
			};		
		</script>
	</head>
	<body>
		<div id="box1"></div>
	</body>
</html>

2.2实现多个div的移动,并优化了代码,让每个div对象拥有自己的timer标识符,并使用回调函数,实现div的形状改变

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			#box1 {
				width: 100px;
				height: 100px;
				background-color: red;
				position: absolute;
				left: 0;
			}

			#box2 {
				width: 100px;
				height: 100px;
				background-color: yellow;
				position: absolute;
				left: 0;
				top: 200px;
			}
		</style>
		<script type="text/javascript">
			window.onload = function() {

				//获取box1
				var box1 = document.getElementById("box1");
				//获取btn01
				var btn01 = document.getElementById("btn01");

				//获取btn02
				var btn02 = document.getElementById("btn02");


				//点击按钮以后,使box1向右移动(left值增大)
				btn01.onclick = function() {
					move(box1, "left", 800, 20);
				};


				//点击按钮以后,使box1向左移动(left值减小)
				btn02.onclick = function() {
					move(box1, "left", 0, 10);
				};


				//获取btn03
				var btn03 = document.getElementById("btn03");
				btn03.onclick = function() {
					move(box2, "left", 800, 10);
				};

				//测试按钮
				var btn04 = document.getElementById("btn04");
				btn04.onclick = function() {
					//move(box2 ,"width", 800 , 10);
					//move(box2 ,"top", 800 , 10);
					//move(box2 ,"height", 800 , 10);
					move(box2, "width", 800, 10, function() {
						move(box2, "height", 400, 10, function() {
							move(box2, "top", 0, 10, function() {
								move(box2, "width", 100, 10, function() {

								});
							});
						});
					});
				};
			};

			//定义一个变量,用来保存定时器的标识
			/*
			 * 目前我们的定时器的标识由全局变量timer保存,
			 * 	所有的执行正在执行的定时器都在这个变量中保存
			 */
			//var timer;

			//尝试创建一个可以执行简单动画的函数
			/*
			 * 参数:
			 * 	obj:要执行动画的对象
			 * 	attr:要执行动画的样式,比如:left top width height
			 * 	target:执行动画的目标位置
			 * 	speed:移动的速度(正数向右移动,负数向左移动)
			 *  callback:回调函数,这个函数将会在动画执行完毕以后执行
			 */
			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;
				}

				//开启一个定时器,用来执行动画效果
				//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
				obj.timer = setInterval(function() {

					//获取box1的原来的left值
					var oldValue = parseInt(getStyle(obj, attr));

					//在旧值的基础上增加
					var newValue = oldValue + speed;

					//判断newValue是否大于800
					//从800 向 0移动
					//向左移动时,需要判断newValue是否小于target
					//向右移动时,需要判断newValue是否大于target
					if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
						newValue = target;
					}

					//将新值设置给box1
					obj.style[attr] = newValue + "px";

					//当元素移动到0px时,使其停止执行动画
					if (newValue == target) {
						//达到目标,关闭定时器
						clearInterval(obj.timer);
						//动画执行完毕,调用回调函数
						callback && callback();
					}

				}, 30);
			}

			/*
			 * 定义一个函数,用来获取指定元素的当前的样式
			 * 参数:
			 * 		obj 要获取样式的元素
			 * 		name 要获取的样式名
			 */
			function getStyle(obj, name) {

				if (window.getComputedStyle) {
					//正常浏览器的方式,具有getComputedStyle()方法
					return getComputedStyle(obj, null)[name];
				} else {
					//IE8的方式,没有getComputedStyle()方法
					return obj.currentStyle[name];
				}

			}
		</script>
	</head>
	<body>

		<button id="btn01">点击按钮以后box1向右移动</button>
		<button id="btn02">点击按钮以后box1向左移动</button>
		<button id="btn03">点击按钮以后box2向右移动</button>
		<button id="btn04">测试按钮</button>

		<br /><br />

		<div id="box1"></div>
		<div id="box2"></div>

		<div style="width: 0; height: 1000px; border-left:1px black solid; position: absolute; left: 800px;top:0;"></div>

	</body>
</html>

2.3轮播图的实现

js+css+html实现源码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			/**
			 * 设置outer的样式
			 */
			#outer{
				width: 500px;
				height: 270px;
				margin:200px auto;
				background-color: #87CEEB;
				padding: 10px 0;
				position: relative;
				/* 裁剪溢出的内容 */
				overflow:hidden;
			}
			#imgList{
				/* 去除项目符号 */
				list-style:none;
				/* 设置ul的宽度 */
				/* width: 2500px; */
				/* 开启绝对定位 */
				position: absolute;
				
				left:0px;
			}
			#imgList li{
				/* 设置图片中的li为水平 */
				float: left;
				/* 设置左右外间距 */
				margin: 0 10px;
			}
			img{
				height: 270px;
				width: 480px;
			}
			/* 设置导航按钮 */
			#navDiv{
				/* 开启绝对定位 */
				position: absolute;
				/*设置位置*/
				bottom: 15px;
			}
			#navDiv a{
				/* 设置超链接向左浮动 */
				float: left;
				/* 设置超链接的宽高 */
				width:15px;
				height:15px;
				
				/* 设置背景颜色 */
				background-color: #87CEEB;
				/* 设置左右外边距 */
				margin: 0 5px;
				/* 设置透明 */
				opacity: 0.5;
				
				/* 兼容IE8透明 */
				filter: alpha(opacity=50);
				
			}			
			/* 设置鼠标移入的效果 */
			#navDiv a:hover{
				background-color: black;
			}
		</style>
		<script type="text/javascript" src="js/tools.js"></script>
		<script type="text/javascript">
			window.onload = function(){
				//设置imgList的宽度
				var imgList = document.getElementById("imgList");
				//获取页面中所有的img标签
				var imgArr = document.getElementsByTagName("img");
				//设置imgList的宽度
				imgList.style.width = 500*imgArr.length+"px";
				
				//设置导航按钮居中
				//获取navDiv
				var navDiv = document.getElementById("navDiv");
				//获取outer
				var outer = document.getElementById("outer");
				//设置navDiv的left值
				navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth)/2 + "px";
				
				//默认显示图片的索引
				var index = 0;
				//获取所有的a
				var allA = document.getElementsByTagName("a");
				//设置默认选中的效果
				allA[index].style.backgroundColor = "black";
				
				/**
				 * 点击超链接切换到指定的图片
				 * 点击第一个超链接,显示第一个图片
				 * 点击第二个超链接,显示第二个图片
				 */
				
				//为所有的超链接绑定单击响应函数
				for(var i=0;i<allA.length;i++){
					//为每一个超链接都添加一个num属性
					allA[i].num = i;
					
					//为超链接绑定单击响应函数
					allA[i].onclick = function(){
						
						clearInterval(timer);
						//获取点击超链接的索引,并将其设置为index
						index=this.num;
						
						setA();
						//使用move函数来切换图片
						move(imgList,"left",-500*index,2000,function(){
							//动画执行完毕,开启自动切换
							autoChange();
						});
						
						
					};
				}
				
				//自动切换图片
				autoChange();
				
				//创建一个方法用来设置选中的图片超链接
				function setA(){
					
					if(index>=imgArr.length-1){
						index = 0;
						imgList.style.left=0;
					}
					
					for(var i=0;i<allA.length;i++){
						//allA[i].style.backgroundColor = "red";内联样式的优先级比hover要高,所以当点了一次后内联样式将hover覆盖了,hover就不起作用了
						//改进,使内联样式的背景颜色为“”,那么样式表中的背景颜色设置就会生效
						allA[i].style.backgroundColor = "";
					}
					//将选中的a设置为黑色
					allA[index].style.backgroundColor = "black";
				};
				
				//定义自动切换的定时器的表示
				var timer;
				//创建一个函数用来开启自动切换
				function autoChange(){
					//开启一个定时器,用来定时去切换图片
					timer = setInterval(function(){
						//使索引自增
						index++;
						
						index %= imgArr.length;
						//判断index的值
						//index %= imgList.length;
						move(imgList,"left",-500*index,20,function(){
							//修改导航按钮
							setA();
						});
					},3000);
				};
				
			};
		</script>
	</head>
	<body>
		<div id="outer">
			<ul id="imgList">
				<li>
					<img src="img/R6S_Wallpaper-01_1920x1080.jpg"/>
				</li>
				<li>
					<img src="img/R6S_Wallpaper-02_1920x1080.jpg"/>
				</li>
				<li>
					<img src="img/R6S_Wallpaper-03_1920x1080.jpg"/>
				</li>
				<li>
					<img src="img/R6S_Wallpaper-04_1920x1080.jpg"/>
				</li>
				<li>
					<img src="img/R6S_Wallpaper-05_1920x1080.jpg"/>
				</li>
				<li>
					<img src="img/R6S_Wallpaper-01_1920x1080.jpg"/>
				</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>

tools.js

//尝试创建一个可以执行简单动画的函数
/*
 * 参数:
 * 	obj:要执行动画的对象
 * 	attr:要执行动画的样式,比如:left top width height
 * 	target:执行动画的目标位置
 * 	speed:移动的速度(正数向右移动,负数向左移动)
 *  callback:回调函数,这个函数将会在动画执行完毕以后执行
 */
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;
	}

	//开启一个定时器,用来执行动画效果
	//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
	obj.timer = setInterval(function() {

		//获取box1的原来的left值
		var oldValue = parseInt(getStyle(obj, attr));

		//在旧值的基础上增加
		var newValue = oldValue + speed;

		//判断newValue是否大于800
		//从800 向 0移动
		//向左移动时,需要判断newValue是否小于target
		//向右移动时,需要判断newValue是否大于target
		if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
			newValue = target;
		}

		//将新值设置给box1
		obj.style[attr] = newValue + "px";

		//当元素移动到0px时,使其停止执行动画
		if(newValue == target) {
			//达到目标,关闭定时器
			clearInterval(obj.timer);
			//动画执行完毕,调用回调函数
			callback && callback();
		}

	}, 30);
}

/*
 * 定义一个函数,用来获取指定元素的当前的样式
 * 参数:
 * 		obj 要获取样式的元素
 * 		name 要获取的样式名
 */
function getStyle(obj, name) {

	if(window.getComputedStyle) {
		//正常浏览器的方式,具有getComputedStyle()方法
		return getComputedStyle(obj, null)[name];
	} else {
		//IE8的方式,没有getComputedStyle()方法
		return obj.currentStyle[name];
	}

}

3.类的操作

  • 通过style属性来修改元素的样式,每修改一个样式浏览器就需要重新渲染一次页面,这样的执行的性能是比较差的,而且这种形式当我们需要修改多个样式时也不太方便
  • js和css一定要分离

希望一行代码可以同时修改多个样式

我们可以修改元素的class属性来间接的修改样式
这样,我们只需要修改一次css,即可同时修改多个样式
浏览器只需要重新渲染页面一次,性能比较好
并且这种方式可以使表现和行为进一步的分离

box.className = "b2";

可以使用两个css类代码,操作如下,就可以同时使用b1和b2中的样式内容了

box.className += " b2";

4.二级菜单

主要思路

  • 使用对二级菜单的行为进行判断,收起和展开状态分别调用css中不同的类
  • 在js中判定选中的一个父级栏目,然后关闭其他栏目
  • 控制栏目的height,以setinterval的方式,实现渐变

html

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>二级菜单</title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
				list-style-type: none;
			}
			
			a,img {
				border: 0;
				text-decoration: none;
			}
			
			body {
				font: 12px/180% Arial, Helvetica, sans-serif, "新宋体";
			}
		</style>

		<link rel="stylesheet" type="text/css" href="css/sdmenu.css" />
		
		<script type="text/javascript" src="js/tools.js"></script>
		<script type="text/javascript">
			window.onload = function(){
				
				/*
				 * 我们的每一个菜单都是一个div
				 * 	当div具有collapsed这个类时,div就是折叠的状态
				 * 	当div没有这个类是,div就是展开的状态
				 */
				
				/*
				 * 点击菜单,切换菜单的显示状态
				 */
				//获取所有的class为menuSpan的元素
				var menuSpan = document.querySelectorAll(".menuSpan");
				
				//定义一个变量,来保存当前打开的菜单
				var openDiv = menuSpan[0].parentNode;
				
				//为span绑定单击响应函数
				for(var i=0 ; i<menuSpan.length ; i++){
					menuSpan[i].onclick = function(){
						
						//this代表我当前点击的span
						//获取当前span的父元素
						var parentDiv = this.parentNode;
						
						//切换菜单的显示状态
						toggleMenu(parentDiv);
						
						
						//判断openDiv和parentDiv是否相同
						if(openDiv != parentDiv  && !hasClass(openDiv , "collapsed")){
							//打开菜单以后,应该关闭之前打开的菜单
							//为了可以统一处理动画过渡效果,我们希望在这将addClass改为toggleClass
							//addClass(openDiv , "collapsed");
							//此处toggleClass()不需要有移除的功能
							//toggleClass(openDiv , "collapsed");
							//切换菜单的显示状态
							toggleMenu(openDiv);
						}
						
						//修改openDiv为当前打开的菜单
						openDiv = parentDiv;
						
					};
				}
				
				/*
				 * 用来切换菜单折叠和显示状态
				 */
				function toggleMenu(obj){
					//在切换类之前,获取元素的高度
					var begin = obj.offsetHeight;
					
					//切换parentDiv的显示
					toggleClass(obj , "collapsed");
					
					//在切换类之后获取一个高度
					var end = obj.offsetHeight;
					
					//console.log("begin = "+begin +" , end = "+end);
					//动画效果就是将高度从begin向end过渡
					//将元素的高度重置为begin
					obj.style.height = begin + "px";
					
					//执行动画,从bengin向end过渡
					move(obj,"height",end,10,function(){
						//动画执行完毕,内联样式已经没有存在的意义了,删除之
						obj.style.height = "";
					});
						
				}
				
				
			};
			
			
		</script>
		
	</head>

	<body>

		<div id="my_menu" class="sdmenu">
			<div>
				<span class="menuSpan">在线工具</span>
				<a href="#">图像优化</a>
				<a href="#">收藏夹图标生成器</a>
				<a href="#">邮件</a>
				<a href="#">htaccess密码</a>
				<a href="#">梯度图像</a>
				<a href="#">按钮生成器</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">支持我们</span>
				<a href="#">推荐我们</a>
				<a href="#">链接我们</a>
				<a href="#">网络资源</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">合作伙伴</span>
				<a href="#">JavaScript工具包</a>
				<a href="#">CSS驱动</a>
				<a href="#">CodingForums</a>
				<a href="#">CSS例子</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">测试电流</span>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
			</div>
		</div>
	</body>
</html>

css文件下文件

  • bottom.gif

  • collapsed.gif

  • expanded.gif

  • linkarrow.gif

  • tittle.gif

  • toptitle.gif

  • sdemenu.css

@charset "utf-8";

/* sdmenu */

div.sdmenu {
	width: 150px;
	margin: 0 auto;
	font-family: Arial, sans-serif;
	font-size: 12px;
	padding-bottom: 10px;
	background: url(bottom.gif) no-repeat right bottom;
	color: #fff;
}

div.sdmenu div {
	background: url(title.gif) repeat-x;
	overflow: hidden;
}

div.sdmenu div:first-child {
	background: url(toptitle.gif) no-repeat;
}

div.sdmenu div.collapsed {
	height: 25px;
}

div.sdmenu div span {
	display: block;
	height: 15px;
	line-height: 15px;
	overflow: hidden;
	padding: 5px 25px;
	font-weight: bold;
	color: white;
	background: url(expanded.gif) no-repeat 10px center;
	cursor: pointer;
	border-bottom: 1px solid #ddd;
}

div.sdmenu div.collapsed span {
	background-image: url(collapsed.gif);
}

div.sdmenu div a {
	padding: 5px 10px;
	background: #eee;
	display: block;
	border-bottom: 1px solid #ddd;
	color: #066;
}

div.sdmenu div a.current {
	background: #ccc;
}

div.sdmenu div a:hover {
	background: #066 url(linkarrow.gif) no-repeat right center;
	color: #fff;
	text-decoration: none;
}

tools.js

//尝试创建一个可以执行简单动画的函数
/*
 * 参数:
 * 	obj:要执行动画的对象
 * 	attr:要执行动画的样式,比如:left top width height
 * 	target:执行动画的目标位置
 * 	speed:移动的速度(正数向右移动,负数向左移动)
 *  callback:回调函数,这个函数将会在动画执行完毕以后执行
 */
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;
	}

	//开启一个定时器,用来执行动画效果
	//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
	obj.timer = setInterval(function() {

		//获取box1的原来的left值
		var oldValue = parseInt(getStyle(obj, attr));

		//在旧值的基础上增加
		var newValue = oldValue + speed;

		//判断newValue是否大于800
		//从800 向 0移动
		//向左移动时,需要判断newValue是否小于target
		//向右移动时,需要判断newValue是否大于target
		if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
			newValue = target;
		}

		//将新值设置给box1
		obj.style[attr] = newValue + "px";

		//当元素移动到0px时,使其停止执行动画
		if(newValue == target) {
			//达到目标,关闭定时器
			clearInterval(obj.timer);
			//动画执行完毕,调用回调函数
			callback && callback();
		}

	}, 30);
}

/*
 * 定义一个函数,用来获取指定元素的当前的样式
 * 参数:
 * 		obj 要获取样式的元素
 * 		name 要获取的样式名
 */
function getStyle(obj, name) {

	if(window.getComputedStyle) {
		//正常浏览器的方式,具有getComputedStyle()方法
		return getComputedStyle(obj, null)[name];
	} else {
		//IE8的方式,没有getComputedStyle()方法
		return obj.currentStyle[name];
	}

}

5.JSON

  • JavaScript Object Notation JS对象表示法
  • js中的对象只有js自己认识,其他语言都不认识
  • JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言识别
    并且可以转换为任意语言中的对象
    -JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号
  • JSON在开发中主要用来作为数据的交互,实现不同语言中数据的传递

JSON分类

1.对象{}
2.数组[]

var obj = '{"name":"jack","age":18,"gender":"man"}';
var arr = '[1,2,3,"hello",true]';

JSON中允许的值

  • 字符串
  • 数值
  • 布尔值
  • null
  • 对象(普通对象,不能是函数对象)
  • 数组

将JSON字符串转换为JS中的对象

  • 在JS中,为我们提供了一个工具类,就叫JSON
  • 这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
  • JSON.parse();
var json = '{"name":"jack","age":18,"gender":"man"}';
var o = JSON.parse(json);

JS对象转JSON

  • Json.stringify();
  • 可以将一个JS对象转换为JSON字符串
  • 需要将一个js对象作为参数,会返回一个JSON字符串
var obj = {"name":"jack","age":18,"gender":"man"};
var json = JSON.stringify(obj);

IE7及以下不支持JSON对象

  • 即不能使用JSON.parse();JSON.stringify();

  • eval()

  • 这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回

  • 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在在字符串前后各加一个()

  • eval这个函数的功能很强大,可以直接执行一个字符串中的js代码,但是在开发中尽量不要使用
    首选他的执行性能比较差,然后它还具有安全隐患

var str2 = "alert('hello')";

var obj = eval("("+str+")");

console.log(obj);
  • 因此推荐的兼容IE7方法为引入一个json.js文件,里面包含有JSON对象的方法
    json2.js
//  json2.js
//  2016-05-01
//  Public Domain.
//  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
//  See http://www.JSON.org/js.html
//  This code should be minified before deployment.
//  See http://javascript.crockford.com/jsmin.html

//  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
//  NOT CONTROL.

//  This file creates a global JSON object containing two methods: stringify
//  and parse. This file is provides the ES5 JSON capability to ES3 systems.
//  If a project might run on IE8 or earlier, then this file should be included.
//  This file does nothing on ES5 systems.

//      JSON.stringify(value, replacer, space)
//          value       any JavaScript value, usually an object or array.
//          replacer    an optional parameter that determines how object
//                      values are stringified for objects. It can be a
//                      function or an array of strings.
//          space       an optional parameter that specifies the indentation
//                      of nested structures. If it is omitted, the text will
//                      be packed without extra whitespace. If it is a number,
//                      it will specify the number of spaces to indent at each
//                      level. If it is a string (such as "\t" or "&nbsp;"),
//                      it contains the characters used to indent at each level.
//          This method produces a JSON text from a JavaScript value.
//          When an object value is found, if the object contains a toJSON
//          method, its toJSON method will be called and the result will be
//          stringified. A toJSON method does not serialize: it returns the
//          value represented by the name/value pair that should be serialized,
//          or undefined if nothing should be serialized. The toJSON method
//          will be passed the key associated with the value, and this will be
//          bound to the value.

//          For example, this would serialize Dates as ISO strings.

//              Date.prototype.toJSON = function (key) {
//                  function f(n) {
//                      // Format integers to have at least two digits.
//                      return (n < 10)
//                          ? "0" + n
//                          : n;
//                  }
//                  return this.getUTCFullYear()   + "-" +
//                       f(this.getUTCMonth() + 1) + "-" +
//                       f(this.getUTCDate())      + "T" +
//                       f(this.getUTCHours())     + ":" +
//                       f(this.getUTCMinutes())   + ":" +
//                       f(this.getUTCSeconds())   + "Z";
//              };

//          You can provide an optional replacer method. It will be passed the
//          key and value of each member, with this bound to the containing
//          object. The value that is returned from your method will be
//          serialized. If your method returns undefined, then the member will
//          be excluded from the serialization.

//          If the replacer parameter is an array of strings, then it will be
//          used to select the members to be serialized. It filters the results
//          such that only members with keys listed in the replacer array are
//          stringified.

//          Values that do not have JSON representations, such as undefined or
//          functions, will not be serialized. Such values in objects will be
//          dropped; in arrays they will be replaced with null. You can use
//          a replacer function to replace those with JSON values.

//          JSON.stringify(undefined) returns undefined.

//          The optional space parameter produces a stringification of the
//          value that is filled with line breaks and indentation to make it
//          easier to read.

//          If the space parameter is a non-empty string, then that string will
//          be used for indentation. If the space parameter is a number, then
//          the indentation will be that many spaces.

//          Example:

//          text = JSON.stringify(["e", {pluribus: "unum"}]);
//          // text is '["e",{"pluribus":"unum"}]'

//          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
//          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

//          text = JSON.stringify([new Date()], function (key, value) {
//              return this[key] instanceof Date
//                  ? "Date(" + this[key] + ")"
//                  : value;
//          });
//          // text is '["Date(---current time---)"]'

//      JSON.parse(text, reviver)
//          This method parses a JSON text to produce an object or array.
//          It can throw a SyntaxError exception.

//          The optional reviver parameter is a function that can filter and
//          transform the results. It receives each of the keys and values,
//          and its return value is used instead of the original value.
//          If it returns what it received, then the structure is not modified.
//          If it returns undefined then the member is deleted.

//          Example:

//          // Parse the text. Values that look like ISO date strings will
//          // be converted to Date objects.

//          myData = JSON.parse(text, function (key, value) {
//              var a;
//              if (typeof value === "string") {
//                  a =
//   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
//                  if (a) {
//                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
//                          +a[5], +a[6]));
//                  }
//              }
//              return value;
//          });

//          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
//              var d;
//              if (typeof value === "string" &&
//                      value.slice(0, 5) === "Date(" &&
//                      value.slice(-1) === ")") {
//                  d = new Date(value.slice(5, -1));
//                  if (d) {
//                      return d;
//                  }
//              }
//              return value;
//          });

//  This is a reference implementation. You are free to copy, modify, or
//  redistribute.

/*jslint
    eval, for, this
*/

/*property
    JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/


// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

if (typeof JSON !== "object") {
    JSON = {};
}

(function () {
    "use strict";

    var rx_one = /^[\],:{}\s]*$/;
    var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
    var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
    var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
    var rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10
            ? "0" + n
            : n;
    }

    function this_value() {
        return this.valueOf();
    }

    if (typeof Date.prototype.toJSON !== "function") {

        Date.prototype.toJSON = function () {

            return isFinite(this.valueOf())
                ? this.getUTCFullYear() + "-" +
                        f(this.getUTCMonth() + 1) + "-" +
                        f(this.getUTCDate()) + "T" +
                        f(this.getUTCHours()) + ":" +
                        f(this.getUTCMinutes()) + ":" +
                        f(this.getUTCSeconds()) + "Z"
                : null;
        };

        Boolean.prototype.toJSON = this_value;
        Number.prototype.toJSON = this_value;
        String.prototype.toJSON = this_value;
    }

    var gap;
    var indent;
    var meta;
    var rep;


    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        rx_escapable.lastIndex = 0;
        return rx_escapable.test(string)
            ? "\"" + string.replace(rx_escapable, function (a) {
                var c = meta[a];
                return typeof c === "string"
                    ? c
                    : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
            }) + "\""
            : "\"" + string + "\"";
    }


    function str(key, holder) {

// Produce a string from holder[key].

        var i;          // The loop counter.
        var k;          // The member key.
        var v;          // The member value.
        var length;
        var mind = gap;
        var partial;
        var value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === "object" &&
                typeof value.toJSON === "function") {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === "function") {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case "string":
            return quote(value);

        case "number":

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value)
                ? String(value)
                : "null";

        case "boolean":
        case "null":

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce "null". The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is "object", we might be dealing with an object or an array or
// null.

        case "object":

// Due to a specification blunder in ECMAScript, typeof null is "object",
// so watch out for that case.

            if (!value) {
                return "null";
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === "[object Array]") {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || "null";
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0
                    ? "[]"
                    : gap
                        ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
                        : "[" + partial.join(",") + "]";
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === "object") {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    if (typeof rep[i] === "string") {
                        k = rep[i];
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (
                                gap
                                    ? ": "
                                    : ":"
                            ) + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (
                                gap
                                    ? ": "
                                    : ":"
                            ) + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0
                ? "{}"
                : gap
                    ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
                    : "{" + partial.join(",") + "}";
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== "function") {
        meta = {    // table of character substitutions
            "\b": "\\b",
            "\t": "\\t",
            "\n": "\\n",
            "\f": "\\f",
            "\r": "\\r",
            "\"": "\\\"",
            "\\": "\\\\"
        };
        JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = "";
            indent = "";

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === "number") {
                for (i = 0; i < space; i += 1) {
                    indent += " ";
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === "string") {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== "function" &&
                    (typeof replacer !== "object" ||
                    typeof replacer.length !== "number")) {
                throw new Error("JSON.stringify");
            }

// Make a fake root object containing our value under the key of "".
// Return the result of stringifying the value.

            return str("", {"": value});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== "function") {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k;
                var v;
                var value = holder[key];
                if (value && typeof value === "object") {
                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            text = String(text);
            rx_dangerous.lastIndex = 0;
            if (rx_dangerous.test(text)) {
                text = text.replace(rx_dangerous, function (a) {
                    return "\\u" +
                            ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with "()" and "new"
// because they can cause invocation, and "=" because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
// replace all simple value tokens with "]" characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or "]" or
// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.

            if (
                rx_one.test(
                    text
                        .replace(rx_two, "@")
                        .replace(rx_three, "]")
                        .replace(rx_four, "")
                )
            ) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval("(" + text + ")");

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return (typeof reviver === "function")
                    ? walk({"": j}, "")
                    : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError("JSON.parse");
        };
    }
}());

posted @ 2021-01-14 23:25  RickZ  阅读(87)  评论(0编辑  收藏  举报