本章节通过练习需要重点掌握轮播图和二级菜单的相关知识点,代码量稍稍多一些,还是需要先理清逻辑再多写几次
如果有问题欢迎及时讨论或留言
120. 修改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>
#box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script>
//w:87,s:83,a:65,d:68
window.onload = function(){
var box = document.getElementById("box");
var speed = 10;
var dir = 0;
setInterval(function(){
if(dir == 87){
box.style.top = box.offsetTop - speed + "px";
}else if(dir == 83){
box.style.top = box.offsetTop + speed + "px";
}else if(dir == 65){
box.style.left = box.offsetLeft - speed + "px";
}else if(dir == 68){
box.style.left = box.offsetLeft + speed + "px";
}
},30);
document.onkeydown = function(e){
e = e || window.e;
dir = e.keyCode;//给方向赋值
if(e.shiftKey){
speed = 50;
}else{
speed = 10;
}
};
document.onkeyup = function(){
dir = 0;
};
}
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>
121. 延时调用
延时调用:延时调用一个函数不马上执行,而是隔一段时间再执行且只执行一次
setTimeout( ),方法,返回Number数据类型,作为唯一标识可以停止延时调用
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据需要选择
<!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>
var num = 1;
//定时调用
// setInterval(function(){
// console.log(num++);
// },3000);
//延时调用
var timer = setTimeout(function(){
alert(num++);
},3000);
</script>
</head>
<body>
</body>
</html>
122. 定时器的应用
为了不影响其它对象的执行,应该不同对象设置不同定时器,可以在执行动画对象obj中添加属性timer作为不同定时器的标识
<!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 rel="stylesheet" href="../fontawesome-free-6.2.0-web/css/all.css">
<style>
button{
width: 100px;
height: 50px;
margin-left: 70px;
}
#dog{
font-size: 50px;
color: brown;
margin-top: 250px;
left: 0;
display: inline-block;
position:absolute;
}
#cat{
font-size: 50px;
color: orange;
left: 0;
position:absolute;
top: 400px;
}
#flag{
font-size: 40px;
color: red;
margin-left: 800px;
}
#des{
font-size: 30px;
color: red;
margin-left: 800px;
}
</style>
<script>
window.onload = function(){
var dog = document.getElementById("dog");
var cat = document.getElementById("cat");
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var btn4 = document.getElementById("btn4");
btn1.onclick = function(){
move(dog,"left",0,10);
};
btn2.onclick = function(){
move(dog,"left",800,11);
};
btn3.onclick = function(){
move(cat,"left",800,10);
};
btn4.onclick = function(){
move(cat,"font-size",800,10,function(){
move(cat,"top",0,10,function(){
move(cat,"left",0,10,function(){
move(cat,"font-size",50,10,function(){
move(cat,"top",400,10);
});
});
});
});
};
};
// var timer;
//move方法参数:obj执行动画对象,attr执行动画样式(如:left,top,width等),
//target目标位置,speed速度,callback回调函数,在动画执行完毕后执行
function move(obj, attr, target, speed, callback){
clearInterval(obj.timer);
var current = parseInt(getStyle(obj,attr));//获取box现在位置
if(current > target){
speed = - speed;
}
obj.timer = setInterval(function(){
var oldvalue = parseInt(getStyle(obj,attr));//获取box原来left
var newValue = oldvalue + speed;//在旧值基础上增加
if((speed < 0 && newValue < target) || (speed >0 && newValue > target)){
newValue = target;
}
obj.style[attr] = newValue + "px";//将新值设置给box
if(newValue == target){//元素移动到目标,停止动画
clearInterval(obj.timer);//关闭计时器
callback && callback();//动画执行完毕,有传回调函数则执行
}
},30);
}
function getStyle(obj,name){
if(window.getComputedStyle){//注意window的使用,加和不加的区别
return getComputedStyle(obj,null)[name];
}
else{
return obj.currentStyle[name];
}
}
</script>
</head>
<body>
<button id="btn1">小狗向左移动</button>
<button id="btn2">小狗向右移动</button>
<button id="btn3">小猫向右移动</button>
<button id="btn4">测试功能按钮</button>
<!-- <div id="box" ></div> -->
<i class="fas fa-dog" id="dog"></i>
<!-- <div id="box1"></div> -->
<i class="fas fa-cat" id="cat"></i>
<h3 id="des">终点!!!</h1>
<i class="fas fa-flag" id="flag"></i>
<div style="width: 0; height: 1000px; border-left: 1px black solid; position: absolute ;left: 800px;top: 30px;"></div>
</body>
</html>
123. 轮播图
<!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 rel="stylesheet" href="../resetstylesheet/reset.css">
<style>
#outer{
width: 420px;
height: 300px;
margin: 50px auto;
background-color: yellowgreen;
padding: 10px 0;
position: relative;
overflow: hidden;
}
#imgList{
list-style: none;
width: 2100px;
position: absolute;
left: 0;
}
#imgList li{
float: left;
margin: 0 10px;
}
#navDiv{
position: absolute;
bottom: 15px;
left: 147px;
}
#navDiv a{
float: left;
width: 15px;
height: 15px;
margin: 0 5px;
background-color: red;
opacity: 0.5; /* 设置透明效果 */
filter: alpha(opacity=50);/* 兼容IE8透明效果 */
}
#navDiv a:hover{
background-color: black;
}
</style>
<script src="../tools/tools.js"></script>
<script>
window.onload = function(){
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
imgList.style.width = 420 * imgArr.length + "px";
var outer = document.getElementById("outer");
var navDiv = document.getElementById("navDiv");
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth)/2 + "px";
var allA = document.getElementsByTagName("a");
var index = 0;//默认显示图片的索引
allA[index].style.backgroundColor = "black";
for(var i=0;i<allA.length;i++){//先执行循环再执行点击事件,i已越界
allA[i].num = i;//为每个超链接添加num属性来判断当前是那个超链接
allA[i].onclick = function(){
clearInterval(timer);//点击的时候停止自动播放
index = this.num;
// imgList.style.left = - 420 * index +"px";
move(imgList,"left",- 420 * index, 20,function(){
autoChange();//点击显示图片完毕开始自动切换
});
setA();
};
}
autoChange();//自动切换图片
//创建设置选中的a颜色的方法
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 = "";//添加了内联样式,hover会失效,设置成空即默认样式
}
allA[index].style.backgroundColor = "black";
};
var timer;
//创建自动切换图片的函数
function autoChange(){
timer = setInterval(function(){
index ++;
index %= imgArr.length;
move(imgList,"left",- 420 * index, 20, function(){
setA();
})
},3000);
}
};
</script>
</head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="../img/1.gif"></li>
<li><img src="../img/2.gif"></li>
<li><img src="../img/3.gif"></li>
<li><img src="../img/4.gif"></li>
<li><img src="../img/5.gif"></li>
<li><img src="../img/1.gif"></li>
</ul>
<div id="navDiv">
<a href="javascript:;">1</a>
<a href="javascript:;">2</a>
<a href="javascript:;">3</a>
<a href="javascript:;">4</a>
<a href="javascript:;">5</a>
</div>
</div>
</body>
</html>
124. 类的操作
通过style属性修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面
执行性能比较差,而且当要修改多个样式时,也不方便
可以对元素的class属性进行修改来简介改变元素的样式,这样只需修改一次即可同时修改多个样式,浏览器也只需重新渲染页面一次,使得性能提升且表现和行为进一步分离
<!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>
.b1{
width: 100px;
height: 100px;
background-color: red;
}
.b2{
width: 200px;
height: 200px;
background-color: yellow;
}
</style>
<script>
window.onload = function(){
var box = document.getElementById("box");
var btn = document.getElementById("btn");
btn.onclick = function(){
// box.style.width = "200px";
// box.style.height = "200px";
// box.style.backgroundColor = "yellow";
// box.className = "b2";
addClass(box,"b2");
alert(hasClass(box,"b2"));
removeClass(box,"b2");
toggleClass(box,"b2");
};
};
//定义一个函数,用来向一个元素中添加指定的class属性值
//参数:obj要添加class属性的元素,cn:要添加的class值
function addClass(obj,cn){
if(!hasClass(obj,cn)){
obj.className += " " + cn;
}
}
//定义一个函数,用来判断一个元素中是否有指定的属性值
//参数:obj,cn
function hasClass(obj,cn){
var reg = new RegExp("\\b"+cn+"\\b");
return reg.test(obj.className);
}
//定义一个函数,用来删除一个元素中指定的class属性值gui
function removeClass(obj,cn){
var reg = new RegExp("\\b"+cn+"\\b");
obj.className = obj.className.replace(reg,"");//属性值换成空串
}
//定义一个函数,用来切换class属性值,如果有则删除,没有则添加
function toggleClass(obj,cn){
if(hasClass(obj,cn)){
removeClass(obj,cn);
}else{
addClass(obj,cn);
}
}
</script>
</head>
<body>
<button id="btn">改变div的样式</button>
<br><br>
<div id="box" class="b1"></div>
</body>
</html>
【注意】开发中能改类尽量改类,不能改类用style,使得JS和CSS足够分离
125. 二级菜单
每一个菜单都是div,当div具有collapsed这个类时,div就是折叠的状态,没有则展开
当给整个div绑定单击响应函数时,由于冒泡,点击超链接时会发生折叠,因此要给div里的span绑定单击响应函数
<!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>二级菜单</title>
<link rel="stylesheet" href="../resetstylesheet/reset.css">
<style>
*{
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" href="./sdmenu.css">
</head>
<script src="../tools/tools.js"></script>
<script>
window.onload = function(){
var menuSpan = document.querySelectorAll(".menuSpan");//获取所有menuSpan元素
var openDiv = menuSpan[0].parentNode;//定义一个变量,保存当前打开的菜单,默认第一个
for(var i=0;i<menuSpan.length;i++){
menuSpan[i].onclick = function(){
var parentDiv = this.parentNode;//this代表当前点击的span,获取当前span的父元素
toggleMenu(parentDiv);//切换菜单的显示状态
if(openDiv != parentDiv && !hasClass(openDiv,"collapsed")){//如果openDiv和parentDiv不相同且openDiv没有collapsed
// addClass(openDiv,"collapsed");//打开菜单以后,关闭之前打开的菜单
// toggleClass(openDiv,"collapsed");//调整为toggleClass统一处理后面过渡动画
toggleMenu(openDiv);
}
openDiv = parentDiv;//修改openDiv为当前打开的Div
};
}
//用来切换菜单的折叠和显示状态
function toggleMenu(obj){
var begin = obj.offsetHeight;//切换类之前,获取元素的高度
toggleClass(obj,"collapsed");//切换parentDiv的显示
var end = obj.offsetHeight;//切换类之后,获取元素的高度
obj.style.height = begin + "px"; //将元素高度重置为begin,内联样式优先,这样才可以执行动画过渡
move(obj,"height",end,10,function(){
obj.style.height= "";//动画执行完毕,删除内联样式
});
}
};
</script>
<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文件:sdmenu.css
@charset "utf-8";
/* sdmenu */
div.sdmenu {
width: 150px;
margin: 100px auto;
font-family: Arial, sans-serif;
font-size: 12px;
padding-bottom: 10px;
background: url(../img/1.gif) no-repeat right bottom;
color: #fff;
}
div.sdmenu div {
background: url(../img/2.gif) repeat-x;
overflow: hidden;
}
div.sdmenu div:first-child{
background: url(../img/3.gif) no-repeat;
}
div.sdmenu div.collapsed{
height: 25px;
}
div.sdmenu div span{
display: block;
height: 15px;
overflow: hidden;
padding: 5px 25px;
font-weight: bold;
color: white;
background: url(../img/4.gif) no-repeat 10px center;
cursor: pointer;
border-bottom: 1px solid #ddd;
}
div.sdmenu div.collapsed span{
background-image: url(../img/5.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(../img/6.gif) no-repeat right center;
color: #fff;
text-decoration: none;
}
tools工具类:tools.js
function move(obj, attr, target, speed, callback) {
clearInterval(obj.timer);
var current = parseInt(getStyle(obj, attr)); //获取box现在位置
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function () {
var oldvalue = parseInt(getStyle(obj, attr)); //获取box原来left
var newValue = oldvalue + speed; //在旧值基础上增加
if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
obj.style[attr] = newValue + "px"; //将新值设置给box
if (newValue == target) {
//元素移动到目标,停止动画
clearInterval(obj.timer); //关闭计时器
callback && callback(); //动画执行完毕,有传回调函数则执行
}
}, 30);
}
function getStyle(obj, name) {
if (window.getComputedStyle) {
//注意window的使用,加和不加的区别
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
}
//定义一个函数,用来向一个元素中添加指定的class属性值
//参数:obj要添加class属性的元素,cn:要添加的class值
function addClass(obj, cn) {
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
//定义一个函数,用来判断一个元素中是否有指定的属性值
//参数:obj,cn
function hasClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
//定义一个函数,用来删除一个元素中指定的class属性值gui
function removeClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
obj.className = obj.className.replace(reg, ""); //属性值换成空串
}
//定义一个函数,用来切换class属性值,如果有则删除,没有则添加
function toggleClass(obj, cn) {
if (hasClass(obj, cn)) {
removeClass(obj, cn);
} else {
addClass(obj, cn);
}
}
126. JSON
JS(JavaScript Object Notation)中对象只有JS能识别,其它语言不能识别
JS对象表示法(JSON)是一个特殊格式的字符串,可以被任何语言识别,并且可以转换为任意语言中的对象
JSON和JS对象格式一样,只不过JSON字符串中的属性名必须加双引号,其它和JS语法一样
而对象中的属性名加单引号或加双引号或不加引号都可
JSON分类:
1.对象{ }
2.数组[ ]
JSON中允许的值:
1.字符串
2.数值
3.布尔值
4.null
5.对象(不包括函数对象)
6.数组
JSON字符串转换为JS对象,使用JSON工具类,该对象可以将一个JSON对象转为JS对象,也可以将JS对象转为JSON对象
JSON- ->JS:JSON.parse( )
例如:var json = ‘{“name”:“张三”,“age”:18,“gender”:“男”}’;
var js = JSON.parse(json);
JS - - >JSON:JSON.stringify( )
例如:var obj = {name:“张三”,age:18,gender:“男”};
var str = JSON.stringify(obj);
JSON对象在IE7及以下的浏览器中不支持
eval( ):方法,可以执行一段字符串形式JS代码返回结果,来将JSON对象转为JS对象
如果使用eval( )执行的字符串中有{ },它会将{ }当成代码块来解析,需在字符串前后各加( )
eval( )功能很强大,可以直接执行一个字符串中的JS代码,在开发中尽量不要使用
1.性能比较差
2.具有安全隐患
因此不推荐使用eval( )
如果需要兼容IE7及以下浏览器的JSON,可以引入一个外部的js文件来处理,其实质是创建JSON对象
<!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 src="../tools/json.js"></script>
<script>
var obj = {name:"张三",age:18,gender:"男"};//JS对象
console.log(obj);
var json = '{"name":"张三","age":18,"gender":"男"}';//JSON对象
var arr = '[1,2,3,"hello",true]';//JSON数组
console.log(json);
var js = JSON.parse(json);//JSON对象转为JS对象
console.log(js);
console.log(js.name);
var jsonObj = JSON.stringify(obj);//JS对象转为JSON对象
console.log(jsonObj);
eval("console.log('hello')");//eval()执行字符串形式JS代码
var jsobj = eval("("+jsonObj+")");
console.log(jsobj);
console.log(jsobj.name);
</script>
</head>
<body>
</body>
</html>
tools工具类:json.js
/*
* @Author: your name
* @Date: 2022-04-08 16:15:12
* @LastEditTime: 2022-04-08 16:15:12
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \web_QD\JavaScript\JavaScript\JAVAScript基础\宿主对象\BOM\js\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 " "),
// 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");
};
}
})();
到此,JavaScript基础入门就结束啦!,谢谢!!!