JS从入门到精通

1.JS概述
window.sessionStorage.setItem("flag", flag);原生JS也可以存SessionStorage
尚硅谷的视频教程:
不用在服务端,在客户端就验证了。
解释型VS编译型;事件驱动;客户端的脚本语言;脚本语言(对环境依赖不强);
加强用户体验;
JavaScript:雷锋、雷锋塔;周杰、周杰伦
(1)语言的介绍:
◆ 计算机是一个有人的机器,人下达什么指令,它来执行什么。
◆ 目的就是人与计算机交流,人通过语言来操作计算机。
◆ 编程语言中英文本质上没有区别,只是语法上的不同。
◆ 语言的发展:机器语言-符号语言-高级语言。
 
(2)起源:
JS诞生与1995年,做网页中的前端验证,用户名长度,密码,邮箱是否正确…
时代需要验证的语言存在,但是当时没有。
除了验证,还有页面的动态效果、游戏等多种实际的应用。
(3)简历史
ECMAScript与JavaScript一般是一个概念。实际上JS含义更大点,一个完整的JS由ECMAScript、DOM、BOM三部分构成。
(4)语言特点:
①解释型语言
②类似于C和Java的语法结构
③动态语言
④基于原型的面向对象
2.使用JS
<!DOCTYPE html>
 <html lang="cn">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
 </head>
 <body>
 <!--页面部分-->
 </body>
 <!--外部js的引入-->
 <script type="text/javascript">
    /* JS代码部分*/
     alert("欢迎来到JS的世界~");
 </script>
 <style type="text/css">
    /* 样式表*/
 </style>
 </html> 要分离的统一维护。
(1)简单的入门打印:
(2)页面中输出内容:
document.writeln("Hello JS");
(3)控制台输出内容:
console.log("Hello JS");
(4)JS的编写位置
<button οnclick="alert('讨厌,点我干什么?')">点我一下</button>
 
<a href="javascript:alert('我去...超链接')">也点击我吧</a>
一般不用这种的写法。
下面这种才是常用的:
<script>
     //JS部分
     alert("我是script里的标签的提示");
     console.log("Hello JS");
 </script>
 
或者编写到外部文件,然后script来引入XXX.js。推荐这种方式。
3.语法、关键字保留及变量
(1)注释,分为多行与单行注释,养成良好的编写注释的习惯。
(2)JS中完全区分大小写。使用方法的时候需要注意。
(3)每条语句以分号结尾,如果不写浏览器会自动资源,但是会消耗一部分资源。性能降低。而且还可能给你加错,在开发中分号必须写。
(4)JS会自动忽略多个空格和换行,可以利用空格和换行对代码进行格式化操作。
(5)字面量:1、2、3这些固定的值。
(6)变量:X、Y、Z,变量可以用来保存字面量,变量的值可以任意改变。变量更加方便我们使用。
var x="13703619524"
 alert(x);
 
(7)可以由我们自主命名的都可以叫做标识符。如变量名、函数名、属性名。命名标识符的时候需要遵守如下规则:标识符中可以有字母、数字、下划线、$符号。标识符不能以数字开头。标识符不能为JS中的保留、关键字。一般采用驼峰命名法(首字母小写,每个单词的开头字母大写,其余小写)。JS底层保存标识符采用的是Unicode编码,所以中文可以作为名字,但是没有直接用中文的,除非神经病。
4.数据类型
(1)类型介绍
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
var a=123;//number
 console.log(typeof a);
 var b='helloWorld';//String
 console.log(typeof b);
 var c=true;//boolean
 console.log(typeof c);
 var d=null;//null
 console.log(typeof d);//这里仍是返回object类型
 var e=undefined;//undefined
 console.log(typeof e);
 var f={};//对象
 console.log(typeof f);
(2)强制数据类型转换
//其他类型转换为String
 var a=123;
 console.log(typeof a);
 console.log(a);
 //调用toString()方法
 var b=a.toString();
 console.log(typeof b);
 console.log(b);
                                              
注意:但是toString对于null与undefined如果调用转换会报错的,他俩就没有toString的方法,调用会报错。
(3)String()函数
//调用String()函数
 var a=456;
 console.log(typeof a);
 console.log(a);
 a=String(a);
 console.log(typeof a);
 console.log(a);
 var a=null;
 console.log(typeof a);
 console.log(a);
 a=String(a);
 console.log(typeof a);
 console.log(a);
这种方式对null与undefined也是可以使用的。对于number和boolean就是调用了toString。但是对于null与undefined就不同了,它会将null转换为“null”,将undefined转换为“undefined”。
(4)数据类型转换为number
//转换为number,使用Number()函数
 var a="123";
 console.log(typeof a);
 console.log(a);
 a=Number(a);
 console.log(typeof a);
 console.log(a);
但是对于123A这种情况,使用Number会变成NaN。如果字符串为空或者多个空格,会转化为0。如果是false转成0,true转成1。Null会转为0。
//第二种方式parseInt()方法,把字符串转换为整数
 //parseFloat()方法,把字符串转换为浮点数
 var a="123px";
 //这里只会去有效的整数内容,从左往右,遇到非数字就停止
 a=parseInt(a);
 console.log(typeof a);
 console.log(a);
 var a="123.567px";
 a=parseFloat(a);
 console.log(typeof a);
 console.log(a);
但是这种适合有数字的转换,如果是布尔值,转换后就是NaN。
(5)进制的转换:
十六进制:0x开头的,八进制以0开头,二进制以ob开头(不是所有的浏览器都支持)。主要还是使用十进制。
var a="070"//IE浏览器会当成八进制解析,谷歌是当成十进制的
 a=parseInt(a,10);//可以指定十进制来转换
 console.log(typeof a);
 console.log(a);
(6)转换为boolean
//转换为boolean,只有一种方式Boolean()函数
 var a=123;
 a=Boolean(a);
 console.log(typeof a);
 console.log(a);
 var a=0;
 a=Boolean(a);
 console.log(typeof a);
 console.log(a);
 var a=NaN;
 a=Boolean(a);
 console.log(typeof a);
 console.log(a);
 var a=-123;
 a=Boolean(a);
 console.log(typeof a);
 console.log(a);
除了0与NaN,其他的都是true。字符串转布尔值,除了空字符串、undfined与null,其余的都是true。
5.运算符
(1)也叫作操作符,可以对一个或多个值进行运算。
//运算符可以对一个或多个值进行运算
 //比如typeof也是运算符
 //运算符都是会返回结果的
 //typeof的返回值是字符串
 var a=123;
 var result=typeof a;
 console.log(result);
 console.log(typeof result);
(2)算术运算符
//算术运算符
 //加减乘除
 //任何值与NaN做运算,最后结果都是NaN
 //两个字符串相加,则会做拼接字符串操作
 var result=2+null;
 console.log(result);
 result=2+NaN;
 console.log(result);
 result=true+1;
 console.log(result);
 result="123"+"456"+"陈翔";
 console.log(result);
 
//任何的值与字符串做+运算,都会先转换为字符串,然后再拼串
 //转成字符串技巧:直接+""空串就可以了
 var result=123+"1";
 console.log(typeof result);
 console.log(result);
 result=true+"陈翔";
 console.log(typeof result);
 console.log(result);
 
//从左往右运算,结果为"33"
 var result=1+2+"3";
 console.log(result);
 result="1"+2+3;
 console.log(result);
 //这个结果是"123"
 
//减法,都是转换为Number
 var a=100-"1";
 console.log(typeof a);
 console.log(a);
 a=2*undefined;
 console.log(typeof a);
 console.log(a);
 a=2*null;
 console.log(typeof a);
 console.log(a);
 
//转换为Number类型的技巧,可以通过-0 /1 *1
 var a="123";
 a=a-0;
 console.log(typeof a);
 console.log(a);
 
//% 取模运算(求余数)
 var a=9 % 2;
 console.log(a);//余数为1
 
(3)一元运算符
//一元运算符,只需要一个操作符
 //+好不影响
 //-能取反
 var a=123;
 a= +a;
 console.log(a);
 
(4)自增和自减
//自增与自减
 var a=1;
 /*a=a+1;
 console.log(a);*/
 a++;
 console.log(a);
 
(5)逻辑运算符
//逻辑运算符 与或非
 //!非运算
 var a=false;
 a=!a;
 console.log(a);//true
 var b=10;
 b=!b;
 console.log(typeof b);
 console.log(b);
 
//&&与 对两侧进行与运算
 var a=true && false;
 console.log(a);
 a=true && true;
 console.log(a);
 a=false && false;
 console.log(a);
 
//||或 对两侧进行或运算
 var a=true || false;
 console.log(a);
 a=true || true;
 console.log(a);
 a=false || false;
 console.log(a);
 
//逻辑运算符 与或非
 //对非布尔值,会先转换为布尔值,然后再运算,
 //但是返回的是非布尔值,谁在后面返回谁
 //如果有0,则会返回0
 var a=2 && 1;
 console.log(typeof a);
 console.log(a);
 a=0 && 1;
 console.log(typeof a);
 console.log(a);
 
(6)赋值运算符
//赋值运算符,将右侧的值赋给左侧的变量
 //=、+=
 var a=123;
 a=a+5;
 console.log(a);
 
(7)关系运算符
//关系运算符,比较两个值的大小关系
 //关系成立则返回true,否则返回false
 //>、>=、<、<=、==
 var a=1>2;
 console.log(a);
 a=1<2;
 console.log(a);
 a=2==2;
 console.log(a);
 a=1>"陈翔";
 console.log(a);
 a=1>"0";
 console.log(a);//true
 
(8)unicode编码表
UTF-8就是对这里面的一个实现,但是UTF-8只是实现其中的一部分。
//unicode编码
 //输出u支持unidoce编码
 //在body里是&#(注意这里后面是十进制)2620对应十进制就是9760
 console.log("u2660");
 console.log("u2620");
 
(9)相等运算符
//相等运算符,用来比较两个值是否相等
 //使用==比较,如果类型不同,将会自动转换相同的来进行比较
 console.log(1==1);
 var a=10;
 console.log(a==4);
 console.log("1"==1);
 //undefined衍生自null
 console.log(undefined===null);
 //NaN不和任何值相等,包括他自身
 //!=与==是相反的
 //===全等,!==不全等
 console.log("1"===1);
 console.log("1"!==1);
(10)条件运算符
//条件运算符
 //条件表达式?语句一:语句二;
 //感觉没有比较函数来的直接,麻烦
 (1>0)?console.log('真的'):console.log('假的');
 (1>2)?console.log('真的'):console.log('假的');
 
(11)运算符的优先级
//运算符的优先级
 //使用,可以划分多个语句
 //就和数学中的优先级一样
 //用括号感觉挺好的
 var result =1+2*3;
 console.log(result);
 //如果优先级一样,则从左往右算
6.流程控制语句
通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。
在 JavaScript 中,我们可使用以下条件语句:
if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码
if...else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码
if...else if....else 语句- 使用该语句来选择多个代码块之一来执行
switch 语句 - 使用该语句来选择多个代码块之一来执行。
(1)代码块
//代码块
 //语句是按照自上而下的顺序一条条执行的
 //可以使用大括号对语句进行分组,每一个都是代码块
 //要么都执行,要么都不执行
 //只有分组的作用,没有其他作用
 {
     var a=10;
     alert('Hello');
     console.log('你好');
     document.write('Hi');
 }
 console.log(a);//也可以执行
 
(2)流程控制语句
//流程控制语句
 //条件判断语句、条件分支语句、循环语句
 //if语句只能控制其后的一条语句,所以想控制多条要用到代码块
 var a=98;
 if(a>60){
     console.log("及格");
 }else{
     console.log("不及格");
 }
 //下面的语句中只会有一个语句被执行,一旦执行了则下面的都不执行了
 //这个写的时候要注意,避免有的代码一直不被执行
 var age=200;
 if(30>=age>17){
     console.log('你成年了');
 }else if(60>=age>30){
     console.log('你中年了');
 }else if(80>=age>60){
     console.log('你已经退休了');
 }else{
     console.log('你岁数挺大的');
 }
 
//流程控制语句
 //条件判断语句、条件分支语句、循环语句
 //prompt()提示框,会带有可输入的文本框
 //用户输入的内容,将会作为此函数的返回值
 var score=prompt("请输入成绩");
 alert('您的成绩为:'+score);
 
(3)条件分支语句
//流程控制语句
 //条件分支语句、循环语句
 //执行将case的值与switch的值进行'全等'比较,比较结果为true,则从当前case开始执行代码 如果所有的都false则执行default语句
 var num=4;
 //根据num的值输出中文
 switch (num) {
     case 1:
         console.log("一");
         break;
     case 2:
         console.log("二");
         break;
     case 3:
         console.log("三");
         break;
     default:
         console.log("其他情况");
         break;
 }
 
(4)循环语句
//循环语句
 //向页面中输出连续的数字
 for(var n=0;n<30;n++){
     document.write(n+'<br/>');
 }
 
//循环语句
 //while循环 {}里的叫做循环体
 //while在执行时,先对表达式进行判断,如果true执行循环体,继续判断执行...
 //如果表达式为false则终止执行
 //如果一直为true则为死循环
 //使用'break'可以退出循环
 var n=0;
 while(n<30){
     document.write(n+'<br/>');
     n++;
 }
 var m=0;
 while(m<30){
     document.write(m+'<br/>');
     m++;
     if(m>10){
         break;
     }
 }
 
//循环语句
 //do...while循环
 
//循环语句
 //for循环
 for(var i=0;i<=100;i++){
     if(i%2!=0){
         console.log(i+'是奇数')
     }
 }
 
//循环语句
 //嵌套for循环
 for(var m=0;m<30;m++){
     for(var n=0;n<20;n++){
         document.write(n+'<br/>');
     }
 }
 
(5)break与continue的使用
//break关键字可以退出switch或循环语句
 //break会立刻终止距离他最近的循环语句
 //使用break语句,可以在后面跟lable,可以结束指定的循环
 outer:
 for(var a=0;a<5;a++){
     console.log(a);
     for(var b=0;b<5;b++){
         console.log(b);
         if(b==3){
             break outer;
         }
     }
 }
 //测试程序性能计时
 console.time('myTime');
 for(var a=0;a<5;a++){
     if(a==3){
         continue;//跳过当次,继续下一次循环
     }
     console.log(a+'------');
 }
 console.timeEnd('myTime');
 
 
7.函数
(1)函数的简介
//函数的简介
 //函数也是一个对象,一切皆对象
 //函数中可以封装一些功能(代码),在需要的时候调用
 //创建一个函数对象
 var myFunction=new Function();
 console.log(typeof myFunction);
 console.log(myFunction);
 //可以将要封装的代码一字符串的形式传递给构造函数
 var myFunction=new Function("console.log('我的第一个函数');");
 console.log(myFunction);
 //但是函数里封装的代码不会立刻执行,会在函数调用时执行
 //调用函数语法,函数对象(),函数中封装的代码会按照顺序执行
 myFunction();
 myFunction();
 myFunction();
 //所以函数对象比普通对象强大
 //但是在实际开发中很少使用构造函数的方法来创建函数
 //使用函数声明来创建函数
 /* function 函数名([参数,参数...]){
      语句...
  }*/
 //函数名不要与构造函数重名...
 function myFunction2(){
     console.log("我的正规方法定义的函数...");
 }
 myFunction2();
 //函数表达式的方式
 /* var 函数名=function(){
 
  }*/
 var myFunction3=function(){
     console.log('匿名函数赋值给变量的方式三...');
 };
 myFunction3();
 
(2)函数的参数
//函数的参数
 //定义一个用来求和的函数
 function mySumFunction(a,b){
     console.log(a+b);
 }
 mySumFunction(4,9);
 //形参,就是形式上的参数,多个形参之间使用逗号隔开
 //在调用函数时,可以在()中指定实参(实际参数)
 mySumFunction(12,98);
 //浏览器不会检查实参的类型
 mySumFunction('Hello','World');
 //所以需要检查下实参是否合法,从而导致程序异常
 //解析器也不会检查实参的数量,多余的实参不用被程序考虑
 mySumFunction('Hello','World',789);
 //如果实参数量,则没有实参的形参将是undefined
 //实参可以是任意的数据类型
 
(3)返回值
//函数的返回值
 //计算三个数的和
 function myFunctionSum(a,b,c){
     //alert(a+b+c);
     return a+b+c;
     //return 执行以后的语句都不会执行
 }
 alert(myFunctionSum(1,2,3));
 //往往执行函数时,结果是需要返回的
 //如果return不跟着或者不写,函数都会返回undefined
 //return可以跟任意类型的值
 
(4)实参可以是任意类型值
//函数的实参
 function myFunctionIsEvenNum(num){
    /* if(num % 2==0){
         return true;
     }else{
         return false;
     }*/
    return num % 2==0;
 }
 var result=myFunctionIsEvenNum(3);
 console.log(result);
 function myFunctionSayHello(name,age){
     console.log('我是'+name,'今年'+age);
 }
 myFunctionSayHello('陈翔',26);
 //如果参数特别多,我写起来就有点麻烦,甚至搞不清顺序
 //创建一个对象
 var myObject={
     name:'陈翔',
     age:26,
     sex:'男',
     site:'广州'
 };
 //如果参数过多,可以封装到对象中,通过对象传递
 function myFunctionSayHi(myObject){
     console.log('我是'+myObject.name,'今年'+myObject.age+
     " 我的性别是"+myObject.sex);
 }
 myFunctionSayHi(myObject);
 //实参也可以是一个函数
 function myFunctionTemp(a){
     console.log('a='+a);
     //如果传函数,a就变成了那个函数
     a(myObject);
 }
 //实参也可以传'函数'
 myFunctionTemp(myFunctionSayHi);
 //如果里面加 调用函数
 //myFunctionTemp(myFunctionSayHi());
 //这种相当于传了括号内函数的返回值,这里要注意
 
(5)返回值的类型
//返回值的类型
 function myFunction(){
     alert("函数要执行了...");
     for(var i=0;i<10;i++){
         console.log(i);
         if(i==2){
             //break可以退出当前循环
             //break;
             //continue用户跳过当次循环
             //return可以结束整个函数
             return;
         }
     }
     alert("函数执行完了...");
 }
 myFunction();
 //函数的返回值可以是任意的数据类型
 //可以返回对象也可以返回函数
 function myFunctionReturn(){
     /*return null;*/
     function myFunctionInner(){
         alert('我是myFunctionInner');
     }
     //函数本身
     return myFunctionInner;
     //函数的调用返回值undefined
     return myFunctionInner();
 }
 var temp=myFunctionReturn();
 console.log(temp);
 
(6)立刻执行函数
//立即执行函数,定义完毕马上被调用
 //立即执行函数往往只会执行一次
 /* (function(){
      alert('我是匿名函数...');
  })();*/
 (function(a,b){
     console.log(a+':'+b);
 })(1,2);
 
(7)方法
//方法
 var myObject=new Object();
 myObject.name='陈翔';
 myObject.age=18;
 //对象的属性值可以是任何的数据类型
 //可以是对象也可是函数
 myObject.sayNameFunction=function(){
     console.log(myObject.name);
 };
 console.log(myObject.sayNameFunction);
 myObject.sayNameFunction();
 //所以函数也可以作为对象属性
 //这种情况我们称此类函数为对象的方法
 //调用函数就是就是调用对象的方法
 //但是他只是名称上的区别,没有其他的区别
 //所以方法与函数本质是相同的,只是名称上有点不同
 var myObject2={
     name:'陈翔',
     age:18,
     //方法的定义是一样的
     sayNameFunction:function(){
         console.log(myObject2.name);
     }
 };
 myObject2.sayNameFunction();
 
(8)枚举
//枚举
 var myObject={
     name:'陈翔',
     age:19,
     sex:'男'
 };
 //怎么知道myObject里有哪些属性,所以要枚举这些属性
 //使用for...in语句
 for(var temp in myObject){
     //console.log('Hello');
     //属性名就可以全部取出来
     console.log(temp+'对应的值'+myObject[temp]);
 }
 
(9)全局作用域
//全局作用域scope
 //两种作用域:全局作用域、局部作用域
 //全局作用域在打开时创建,在页面关闭是销毁
 //全局作用域中有一个全局对象window(代表的是浏览器的窗口),我们可以直接使用
 //创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存
 //所以a与window.a是一样的作用
 console.log(window);
 var temp=456;//全局
 function myFunction(){
     //局部的
     var a=123;
 }
 //这里无法直接饮用
 console.log(window.temp);
 //变量的声明提前
 //var关键字声明的变量,会在所有的代码执行之前被声明
 //如果不使用var,则不会被声明提前
 var c=123;
 console.log('c='+c);
 function myFunction(){
     console.log('我是一个函数...');
 }
 var myFunctionTwo=function(){
     console.log('我是第二个函数...');
 }
 //函数的声明提前 function 函数(){},会在所有的代码执行之前被创建
 //所以这种方法,可以在函数声明前被调用。
 //但是 var myFunctionTwo=function(){}就不能声明提前,所以不能在声明前调用。
 //全局作用中的变量都是全局变量。在页面的任意部位都可以访问到。
 
(10)函数作用域
//函数作用域,也就是局部变量
 //调用函数时创建作用域,函数执行完毕后,作用域销毁
 //没调用一个函数都会创建一个新的函数作用域,他们之间互相独立。
 //在函数作用域中可以访问到全局作用域的变量。
 var a=10;
 function myFunction1(){
     var a='我是函数作用域的a';
     var b=20;
     console.log('内部输出a='+a);
 }
 myFunction1();
 console.log('外部输出a='+a);
 //在全局作用域中,无法访问到函数作用域的变量
 //console.log('b='+b);//会报错
 //当在函数作用域中操作一个变量时,会先在自身寻找,如果有则直接使用,如果没有则去上一级作用域去找
 //上一级不一定就是全局作用域,也可能是上一级的函数作用域
 //原则是从内往外找,直到找到全局作用域,如果还是没有则会报错XXX is not defined
 //如果在函数里想访问全局变量,可以在前面加上window.
 //函数作用域中也存在var提前声明与函数的提前创建
 var c=33;
 function myFunction5(){
     console.log('c='+c);
     c=35;
 }
 myFunction5();
 console.log('外部的c='+c);
 //在函数中不声明的变量都会成为全局变量
 //形参就相当于在函数作用域中声明了变量
 
(11)DEBUG
//Debug
 alert(d);
 var a=10;
 var b='Hello';
 c=true;
 function myFunction(){
     alert('Hi');
 }
 var d=35;
 //谷歌浏览器调出开发者模式
 //Sources-打断点-然后添加Watch里想监控的变量
 //一步步执行就可以看执行顺序了
(12)this的说明
//this的说明
 //调用myFunction的时候实际上是由隐藏参数this传递的
 //this指向的是一个对象,是函数执行的上下文对象
 //根据函数调用方式的不同,this会指向不同的对象
 //1.以函数的形式调用,this永远指向的是window
 //2.以方法的形式调用,this指向的是调用方法所在的对象。
 function myFunction(a,b){
     //console.log(a+';'+b);
     console.log(this);
 }
 myFunction(123,456);
 var myObject={
     name:'孙悟空',
     sayName:myFunction
 }
 console.log(myObject.sayName==myFunction);
 myFunction();
 myObject.sayName();
 var myObject1={
     name:'陈翔',
     sayName:myFunction
 }
 myObject1.sayName();
 
8.对象与数组
(1)概述
//对象Object
 //基本数据类型:String、Number、Boolean、null、Undefined。不是基本类型:Object
 //如果在JS中表示人的信息
 //如果使用基本数据类型,会发现创建的变量都是独立的。
 //对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
 //对象的分类:1.内建对象 比如Math String Number...
 //          2.宿主对象 BOM DOM中的对象
 //          3.自定义对象,开发者自己创建的对象
 
(2)对象的创建与增删改查
//对象Object的创建
 //new调用的函数是构造函数constructor,是专门创建对象的函数
 var myObject=new Object();
 //向对象中添加属性,在对象中保存的值叫做属性
 myObject.name='陈翔';
 myObject.age=26;
 myObject.sex='男';
 console.log(typeof myObject);
 console.log(myObject);
 //读取对象中的属性
 console.log(myObject.name);
 //修改属性值
 myObject.name='蘑菇头';
 console.log(myObject);
 //删除属性delete 对象.属性名
 delete myObject.sex;
 console.log(myObject);
 
(3)属性名与属性值
//属性名与属性值
 //属性名可以随意定义,尽量注意规范即可
 //如果是123这种特殊的名字,要用myObject['123'],当然取的时候也是myObject['123']
 //中括号的形式可以更加灵活
 /*var myObject=new Object();
 myObject.name='陈翔';
 console.log(myObject);*/
 var myObject=new Object();
 myObject['name']='陈翔';
 for(var m=0;m<5;m++){
     myObject[m]=m+"->";
 }
 console.log(myObject);
 
//属性名与属性值
 //属性值
 var myObject=new Object();
 myObject.name=true;
 console.log(myObject.name);
 myObject.name=null;
 console.log(myObject.name);
 var myObject2=new Object();
 myObject2.age=26;
 myObject.name=myObject2;//值也可以是对象
 console.log(myObject);
 //检查对象是否包含某个属性
 //in 运算符,检查对象中是否含有指定的属性
 console.log('test2' in myObject);
 console.log('name' in myObject);
 
(4)基本数据类型与引用数据类型
//基本数据类型String Number Boolean Null Undefined
 //引用数据类型Object
 var a=123;
 var b=a;
 a=a+1
 console.log('a的值:'+a);
 console.log('b的值:'+b);
 //说明a的值变化,不影响b的值
 
 var myObject=new Object();
 myObject.name='陈翔';
 var myObject2=myObject;
 myObject.name='蘑菇头';//这里的改变,却影响了myObject2.name的值
 console.log('myObject的名字:'+myObject.name);
 console.log('myObject2的名字:'+myObject2.name);
 //这就是最基本的区别
 
基本数据类型:
 
引用数据类型:
 
比较引用数据类型,它是比较的是对象的内存地址。如果两个对象一样,但是地址不同,也是会返回false的。所以这两个对象相比较相等则需要myObject.name与myObject2.name拿出来比较才可以。
 
(5)对象字面量
//对象字面量
 var myObject={};
 myObject.name='陈翔';
 console.log(typeof myObject);
 console.log(myObject);
 //使用对象字面量,可以在创建对象时指定对象中的属性
 //对象字面量的属性名可以加引号,也可以不加,建议不加
 //如果是特殊的名字需要加引号
 //属性名与属性值是一组一组的名值对结构
 //多个名值之间用逗号隔开,如果是最后一对则不用写逗号了
 var myObject2={
     name:'陈翔',
     age:26,
     sex:'男',
     dog:{
         name:'小黑',
         age:2
     }
 };
 console.log(typeof myObject2);
 console.log(myObject2);
 
(6)使用工厂方法创建对象
//使用工厂方法创建对象
 //比如需要创建10个类似的对象,如果更简单点
 function myFunctionCreatePerson(name,age,sex){
     //通过该方法大批量创建对象
     var myObject=new Object();
     //向对象中添加属性
     myObject.name=name;
     myObject.age=age;
     myObject.sex=sex;
     myObject.sayName=function(){
         console.log('你好,我是'+this.name)
     }
     //将新对象返回
     return myObject;
 }
 var myObject1=myFunctionCreatePerson('陈翔',26,'男');
 var myObject2=myFunctionCreatePerson('球球',28,'女');
 var myObject3=myFunctionCreatePerson('冷萌',23,'女');
 console.log(myObject1);
 console.log(myObject2);
 console.log(myObject3);
 
(7)构造函数的形式创建类
//使用工厂方法创建对象,使用的构造函数都是Object
 //类型都是Object就导致我们无法区分出多种不同类型的对象
 //所以我们要用构造函数的方式
 //创建一个构造函数,专门来创建person对象
 //不同的是,构造函数是首字母大写。
 //普通函数直接调用,new关键字就是构造函数的调用。
 //构造函数的执行流程
 /**1.立刻创建一个新的对象
    2.将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
    3.逐行执行函数中的代码
    4.将新的对象作为返回值返回
   */
 //这样我们就可以更好的区分Person与Dog了
 function Person(name,age,sex){
     this.name=name;
     this.age=age;
     this.sex=sex;
 }
 var myPerson=new Person('陈翔',26,'男');
 var myPerson1=new Person('蘑菇头',27,'男');
 var myPerson2=new Person('闰土',28,'男');
 console.log(myPerson);
 console.log(myPerson1);
 console.log(myPerson2);
 function Dog(name,age){
     this.name=name;
     this.age=age;
 }
 var myDog=new Dog('小黄',2);
 console.log(myDog);
 //instanceof可以检查一个对象是否是一个类的实例
 console.log(myDog instanceof Person);
Object是所有对象的祖先,比如例子中的Person与Dog,如果用instaceof检查是否属于Object都会返回true。、
A.     This当以函数的形式调用时,this是window
B.     This当以方法的形式调用时,谁调用方法this就是谁
C.     This当以构造函数的形式调用时,this就是新创建的那个对象
(8)构造函数的修改
/**1.创建一个Person构造函数
  * 2.但是构造函数创建方法,每个对象都有sayName方法
  * 3.这样就导致构造函数每执行一次,就创建了一次sayName方法,而这样的方法都是一样的
  *  是完全没有必要的,完全可以是所有的对象共享同一个方法。
   */
 //这样我们就可以更好的区分Person与Dog了
 function Person(name,age,sex){
     this.name=name;
     this.age=age;
     this.sex=sex;
     this.sayName=myFunction;
 }
 //将sayName方法在全局作用域中定义
 //这个在性能上有很大的提升
 function myFunction(){
     console.log(this.name);
 }
 var myPerson=new Person('陈翔',26,'男');
 myPerson.sayName();
 
(9)forEach()遍历方法
//提供的遍历方法forEach()
 //仅支持IE8以上的浏览器
 var myArray=['陈翔','蘑菇','球球','冷萌'];
 //需要一个函数作为参数
 //像这种函数,由我们创建,但是不由我们调用的,我们称之为回调函数。
 //数组中有几个元素,函数就回执行几次
 //每次遍历到元素会以实参的形式传递进来,我们可以定义形参来读取这些内容。
 //浏览器会在回调函数中传递三个参数
 //第三个参数就是正在遍历的数组
 myArray.forEach(function(value,index){
     console.log('-----');
     console.log(index+':'+value);
 });
 
(10)原型对象
//原型对象
 //全局作用域污染了全局作用的命令空间
 //原型prototype
 //我们所创建的每一个函数,我们的解析器都会向函数中添加一个属性prototype
 //这个属性对应一个对象,这个对象就是我们所说的原型对象
 //如果函数作为普通函数调用,prototype没有任何作用
 //当以构造函数的形式调用时,他所创建的对象中会有一个隐含的属性
 //原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
 //所以我们可以将对象中的共有内容,统一设置到原型对象中
 function Person(){
 
 }
 /*console.log(Person.prototype);
 var myPerson=new Person();
 console.log(myPerson.__proto__==Person.prototype);
 var myPerson2=new Person();
 console.log(myPerson2.__proto__==Person.prototype);*/
 //myPerson.myNum='我是myPerson中的...';
 var myPerson=new Person();
 Person.prototype.myNum=123;
 //当我们访问对象按给你属性或方法时,会先在对象自身寻找,如果有则直接使用
 //如果没有则去原型对象找,如果有则使用
 var myPerson=new Person();
 console.log(myPerson.myNum);
 Person.prototype.sayName=function(){
     console.log('原型里的方法调用ing...');
 }
 myPerson.sayName();
 //以后创建构造函数时,可以统一添加到构造函数的原型对象中,这样可以不用分别
 //为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有属性和方法
 
//原型对象
 function Person(){
 
 }
 var myPerson=new Person();
 //向原型对象中添加一个name属性
 Person.prototype.name='我是原型中的名字';
 console.log(myPerson.name);
 //使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
 console.log('name' in myPerson);
 //可以用hasOwnProperty检查对象自身是否含有该尚需经
 console.log(myPerson.hasOwnProperty('name'));
 myPerson.age=18;
 console.log(myPerson.hasOwnProperty('age'));
 //原型对象里还有原型,因为原型对象也是对象
 //当使用对象的属性或方法时,会在自身中寻找,
 //如果有,则直接使用
 //如果没有则去原型对象中寻找,如果原型对象中有,则使用
 //如果没有则去原型的原型中寻找,看是否有...
 //从下面的代码,可以看到是在原型的原型里。
 //知道找到Object对象的原型,Object对象的原型没有原型
 //如果仍然没有找到,则返回undefined
 console.log(myPerson.__proto__.__proto__.hasOwnProperty('hasOwnProperty'));
 
(11)toString()方法
//toString()
  function Person(name,age){
      this.name=name;
      this.age=age;
  }
  var myPerson=new Person('陈翔',26);
  //之类实际输出的是对象的toString()方法的返回值
  //console.log(myPerson);
  console.log(myPerson.__proto__.__proto__.hasOwnProperty('toString'));
  //如果我们希望在输出对象时不输出默认样式,可以自行添加toString()方法
 /* myPerson.toString=function(){
      return '我自定的toString返回值';
  };*/
  Person.prototype.toString=function(){
      return this.name+': '+this.age;
  };
  console.log(myPerson.toString());
 
(12)垃圾回收
//1.垃圾回收GC
 //就想人生活时间长会产生垃圾一样,程序运行过程中也会产生垃圾
 //所以我们需要一个垃圾回收极致,来处理程序运行过程中产生的垃圾
 var myObject=new Object();
 //对对象进行各种操作...
 //2.当一个对象没有任何的变量或者属性对它进行引用,此时我们无法操作
 //该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,
 //导致程序变慢,必须进行清理
 //3.JS中有用自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
 //我们不需要也不能进行垃圾回收的操作,我们需要做的是将不再用的对象
 //设置为null
 myObject=null;
 
(13)数组
//1.内建对象、宿主对象、自定义对象
 //2.数组Array,数组也是一个对象,它和我们普通的对象功能类似,
 //不同的是普通对象是使用字符串作为属性名的,而数组是用数字
 //作为索引来操作元素的。
 //索引是从0开始的,可以使用数组来存储一些数据
 //3.创建数组对象
 var myArray=new Array();
 console.log(myArray);
 console.log(typeof myArray);
 //向数组中添加元素
 myArray[0]=10;
 myArray[1]=33;
 console.log(myArray);
 //读取数组中的元素
 console.log(myArray[0]);
 //读取不存在的索引会返回undefined
 console.log(myArray[3]);
 //获取数组的长度,也就是元素的个数
 console.log(myArray.length);
 //对于非连续的数组,使用length会获取到数组的最大索引+1
 myArray[10]=1010;
 console.log(myArray.length);
 console.log(myArray);
 //如果修改的length大于原长度,则会空出来多出的部分
 //如果修改的length小于原长度,则多出的元素会被删除
 //永远都像数字的最后以为添加
 //则可以用下面的方式,这是一个技巧
 myArray[myArray.length]=70;
 console.log(myArray);
 
(14)数组字面量
//数组字面量
 //使用字面量来创建数组
 var myArray=[1,2,3,4,5];
 console.log(myArray);
 console.log(myArray.length);
 var myArray1=new Array(1,2,3,4,5);
 //这种方式是一样的
 console.log(myArray1);
 console.log(myArray1.length);
 //数组的元素可以是任意的数据类型
 var myArray2=['Hello',true,1,null,undefined];
 console.log(myArray2);
 console.log(myArray2.length);
 //也可以放对象
 var myObject={
     name:'陈翔'
 };
 myArray2[myArray2.length]=myObject;
 console.log(myArray2);
 console.log(myArray2.length);
 console.log(myArray2[5]);
 //JSON
 var myArray3=[{name:'陈翔'},{name:'陈翔'}];
 console.log(myArray3);
 //也可以放函数
 myArray3=[function(){console.log('Hi')},function(){console.log('Hi')}];
 console.log(myArray3);
 //数组里也可以放数组,这种叫做二维数组
 myArray3=[[1,2],[1,2],[1,2]];
 
(15)数组的四个方法
//数组的方法
 var myArray=['孙悟空','猪八戒','沙和尚'];
 //push()向数组末尾添加一个元素,并返回数组的新长度
 var myPushReturn=myArray.push('唐僧','白骨精');
 console.log(myArray);
 //返回的是数组的新长度
 console.log(myPushReturn);
 //pop()删除并返回数组的最后一个元素
 //返回的是被删除的元素
 var myPopReturn=myArray.pop();
 console.log(myArray);
 console.log(myPopReturn);
 //unshift()向数组的开头添加一个或多个元素
 //并返回新的长度
 var unshiftReturn= myArray.unshift('牛魔王','红孩儿');
 console.log(myArray);
 console.log(unshiftReturn);
 //shift()是删除之前的元素
 //返回的也是删除的元素
 var shiftReturn= myArray.shift();
 console.log(myArray);
 console.log(shiftReturn);
 
(16)数组的遍历
//数组的遍历
 var myArray=['孙悟空','猪八戒','沙和尚','唐僧'];
 for(var i=0;i<myArray.length;i++){
     console.log(myArray[i]);
 }
 
(17)slice和splice方法
//slice()
 var myArray=['关羽','赵云','诸葛亮','马超'];
 console.log(myArray);
 //可以从数组中提取元素,包含开始不包含结束
 var sliceArray=myArray.slice(0,2);
 console.log(sliceArray);
 //下标也可以用负数,但是不推荐使用
 //splice()可以用于删除数组的指定元素
 //后面的是表示删除几个
 console.log(myArray);
 var spliceArray=myArray.splice(0,2);
 //这里myArray就回被删除两个元素
 //返回的是删除的元素
 console.log(myArray);
 console.log(spliceArray);
 //第三个参数及以后可以传递一些新的元素,这些元素
 //将会自动插入到开始位置的前边。
 spliceArray=myArray.splice(0,1,'典韦');
 console.log(myArray);
 console.log(spliceArray);
 
//数组去重
 var myArray=[1,2,3,3,3,3,3,3,3,3,4,5,6,1,2,3,4];
 for(var i=0;i<myArray.length;i++){
     for(var j=i+1;j<myArray.length;j++){
         if(myArray[i]==myArray[j]){
             myArray.splice(j,1);
             //当删除当前j对应的元素后,后边的元素
             //会自动补位,此时将不会再比较这个
             //元素,所以我需要再比较一次j所在的元素
             j--;
         }
     }
 }
 console.log(myArray);
 
(18)关于数组的其他方法
//数组相关的方法
 var myArray=['陈翔','球球','蘑菇头'];
 var myArray2=['闰土','冷檬','妹大爷'];
 //concat()可以连接两个或多个数组,并将新的数组返回
 var concatReturn=myArray.concat(myArray2);
 console.log(concatReturn);
 //join()该方法可以将数组转换为字符串
 //不会对原数组产生影响
 //可以指定连接符,不指定是逗号,可以使用空格连接符
 var joinReturn=myArray.join();
 console.log(joinReturn);
 var joinReturn=myArray.join('--');
 console.log(joinReturn);
 var joinReturn=myArray.join('@');
 console.log(joinReturn);
 //reverse()该方法用来反转数组(前边的去后面,
 //后面的去前面)
 //该方法会直接修改原数组
 myArray.reverse();
 console.log(myArray);
 //sort()对数组的元素进行排序
 //也会影响原数组
 //按照unicode编码进行排序
 var myArray2=['a','d','e','b','f'];
 console.log(myArray2);
 myArray2.sort();
 console.log(myArray2);
 //这种根据unicode编码排序就会出现问题
 var myArray3=[1,2,3,4,11,5,6,12,23,22];
 myArray3.sort();
 console.log(myArray3);
 //所以要自定义排序
 myArray3.sort(function(a,b){
    /* if(a>b){
         return 1;
     }else{
         return -1;
     }*/
    return a-b;//代码的优化,降序就是b-a
 });
 console.log(myArray3);
 
(19)函数的方法call()与apply()
//函数的方法
   function myFunction(){
       alert(this);
   }
   //call与apply都是函数对象的方法 ,需要通过函数对象来调用
 /*  myFunction.call();
   myFunction.apply();
   myFunction();*/
   //上面三个是同一个效果
   //不同的是,在调用call与apply可以将一个对象指定为第一个参数
   //此时这个对象将会成为函数执行时的this
   myFunction();
   var myObject={};
   myFunction.call(myObject);
   //所以这两个函数的主要作用是修改上下文对象this
   //apply方法需要将实参封装到数组中统一传递
   //call可以一个个传
   //this情况总结:
   //1.以函数的形式调用,this永远是window
   //2.以方法的形式调用,this是调用方法的那个对象
   //3.使用call与apply调用时,this是指定的那个对象
   //4.以构造函数调用时,this是创建的那个对象
 
(20)arguments
//函数的arguments
 function myFunction() {
     console.log(arguments);
     console.log(arguments instanceof Array);
     console.log(arguments.length);
     console.log(arguments.callee);
 }
 //调用函数时,浏览器每次都会传递进来两个隐藏的参数
 //1.函数上线文对象this
 //2.封装实参的对象arguments
 myFunction();
 //arguments是一个类数组对象
 //也可以通过索引来操作数据,也可以获取长度
 //在调用函数时,我们所传递的实参都会在arguments中保存
 myFunction('Hi','Say');
 //arguments[0]、arguments[1]表示第N+1个实参
 //callee属性,这个属性对应一个函数对象
 //就是当前正在执行的函数的对象
 
(21)Date对象
//Date对象
 //直接使用构造函数创建一个Date对象,则会封装当前代码执行的时间
 var myDate=new Date();
 console.log(myDate);
 //创建指定时间的对象
 //日期的格式 月份/日/年 时:分:秒
 var myDate1=new Date("12/05/2021 11:10:30");
 console.log(myDate1);
 //获取当前对象是几号
 var tempDate=myDate1.getDate();
 console.log("几号tempDate: "+tempDate);
 //获取当前日期对象是周几
 //0-6分别表示周日-周六
 tempDate=myDate1.getDay();
 console.log("星期tempDate: "+tempDate);
 //获取当前对象的月份
 //0-11表示1-12月,0表示1月份
 tempDate=myDate1.getMonth();
 console.log("月份tempDate: "+tempDate);
 //获取当前日期对象的年份
 tempDate=myDate1.getFullYear();
 console.log("年份tempDate: "+tempDate);
 //时间戳,从格林威治标准时间1970年1月1日,0分0秒
 //到当前日期所耗费的毫秒数
 //计算机底层在保存时间使用的都是时间戳
 tempDate=myDate1.getTime();
 console.log("时间戳毫秒tempDate: "+tempDate);
 //来看下特例,这里默认的是中八区的时间
 //所以改成8:0:0就相当于格林威治的0:0:0
 myDate1=new Date("1/1/1970 8:0:0");
 tempDate=myDate1.getTime();
 console.log("时间戳毫秒tempDate: "+tempDate);
 var startTime=Date.now();
 for(var i=0;i<100;i++){
     console.log(i);
 }
 var endTime=Date.now();
 console.log("共计耗时毫秒 "+(endTime-startTime));
 
(22)Math对象
//Math对象
 console.log(Math);
 //Math和其他函数不同,它不是一个构造函数
 //他属于一个工具类,不用创建对象,它里面封装了数学
 //运算的属性与方法
 console.log("圆周率 "+Math.PI);
 //abs()可以计算一个数的绝对值
 console.log("-36的绝对值 "+Math.abs(-36));
 //向上取整
 console.log("1.2的向上取整 "+Math.ceil(1.2));
 //向下取整
 console.log("1.9的向下取整 "+Math.floor(1.9));
 //四舍五入取整
 console.log("1.4四舍五入取整 "+Math.round(1.4));
 console.log("1.6四舍五入取整 "+Math.round(1.6));
 //随机数
 console.log("0-1之间的随机数 "+Math.random());
 console.log("0-10之间的随机数 "+Math.round(Math.random()*10));
 //生成X-Y之间的随机数
 //Math.round((Math.random()*y-x)+x)
 //max()获取多个数中的最大值
 console.log("找最大值 "+Math.max(10,1,2,45,100));
 console.log("找最小值 "+Math.min(10,1,2,45,100));
 //Math.pow(x,y) x的y次方
 console.log(Math.pow(2,4));
 //开方
 console.log(Math.sqrt(2));
 
9.类与正则表达式
(1)包装类
//数据类型
 //1.基本数据类型、引用数据类型
 //2.JS中提供了三个包装类,可以将基本的数据类型转换为对象
 //String()变成String对象
 //Number()变成Number对象
 //Boolean()编程Boolean对象
 var a=123;
 console.log(typeof a);
 var num=new Number(3);
 //这是是Object对象类型
 console.log(typeof num);
 num.name="陈翔";
 //对象更强大,可以添加属性
 console.log(num.name);
 var str=new String('Hello');
 console.log(typeof str);
 var myFlag=new Boolean(true);
 console.log(typeof myFlag);
 //实际中不会使用基本数据类型的对象
 //如果使用基本数据类型对象,进行比较时可能会带来
 //与预期不同的后果。
 //→当我们对一些基本数据类型的值去调用属性和方法时
 //浏览器会"临时"使用包装类将其转换为对象,然后再调用
 //对象的属性和方法。调用完毕后再转换为基本数据类型。
 var s=123;
 s=s.toString();
 console.log(s);
 console.log(typeof s);
 s.name='蘑菇头';
 //这里将打印undefined,因为原s被销毁了
 //新的s读是没有这个属性的,所以会undefined
 console.log(s.name);
 
(2)字符串方法
//创建一个字符串
 var str="Hello,HIT";
 //底层字符串是以字符数组的形式保存的
 //['H','e','l'....]
 console.log(str.length);
 for(var i=0;i<str.length;i++){
     //console.log(str[i]);
 }
 //length可以获取字符串的长度
 //charAt()可以返回字符串中指定位置的字符
 console.log(str.charAt(6));
 //charCodeAt()
 //获取指定位置字符的编码(unicode编码)
 console.log(str.charCodeAt(0));
 //fromCharCode()可以根据字符编码取字符
 //unicode对照表是16进制可以用0x...来表示
 console.log(String.fromCharCode(20013));
 //concat()可以连接两个或多个字符串
 var result=str.concat('你好');
 console.log(result);
 //indexOf()该方法可以检索一个字符串是否包含指定
 //内容,返回字符串所在的位置。
 //如果没有找到则返回-1
 //也可以从指定位置查找
 result=str.indexOf('H');
 console.log('str中是否包含H,位置为 '+result);
 result=str.indexOf('T');
 console.log('str中是否包含H,位置为 '+result);
 result=str.indexOf('0');
 console.log('str中是否包含H,位置为 '+result);
 //lastIndexOf
 //1.与indexOf(从前往后找)一样,lastIndexOf是从后往前找
 //2.也可以指定开始查找的位置
 result=str.lastIndexOf('H');
 console.log('str中是否包含H,位置为 '+result);
 //slice()
 //1.可以从字符串中截取指定的内容
 //2.不会影响原字符串(包括开始)
 //3.第一个参数开始位置,第二个是结束位置(不包括结束)
 //4.如果省略第二个参数,则会截取到后面所有的
 //5.如果第二个传负值,则从后面开始截取
 console.log(str.slice(0,2));
 //substring()
 //1.可以用来截取一个字符串,与slice()类似
 //2.参数开始位置、结束位置(不包括结束位置)
 //3.不同的是substring不能传负的参数
 //4.而且会自动调整参数位置,如果第二个参数小于第一个
 //参数,则自动调整参数位置。
 console.log(str.substring(0,2));
 //split()
 //1.可以将字符串拆分为一个数组
 //2.需要字符串作为参数
 //3.如果传递一个空串作为参数,则将每个字符都拆分为
 //数组中的一个元素
 str='1,2,34,6,9';
 result=str.split(',');
 console.log(result);
 console.log(Array.isArray(result));
 //toLocaleLowerCase()、toLocaleUpperCase()
 str='Hello';
 console.log(str.toLocaleUpperCase());
 
(3)正则表达式
//正则表达式
 //1.如邮件的校验
 //(1)前面可以是XXX
 //(2)跟着一个@
 //(3)后边是XXX.com
 //2.正则表达式就是一定字符串的规则
 //计算机来根据正则表达式来检查一个字符串是否符合
 //规则,或者将字符串中符合规则的内容提取出来
 //3.创建正则表达式对象
 //(1)RegExp('正则表达式','匹配模式');
 var myRegExp=new RegExp('a');
 console.log(myRegExp);
 console.log(typeof myRegExp);
 var checkStr='Abc';
 //(2)正则表达式的方法test()
 //单独new RegExp('a');可以检查字符串中是否含有a
 var checkFlag=myRegExp.test(checkStr);
 console.log(checkFlag);
 //checkStr必须包含小a才可以返回true
 //是严格区分大小写的
 //(3)RegExp('正则表达式','匹配模式');
 //匹配模式i 忽略大小写;g 全局匹配模式
 myRegExp=new RegExp('a','i');
 checkFlag=myRegExp.test(checkStr);
 console.log(checkFlag);
 
(4)正则语法
//正则语法
 //1.var myRegExp=new RegExp();
 //2.也可以使用字面量来创建正则表达式
 //语法:var 变量=/正则表达式/匹配模式
 var myRegExp=/a/i;
 console.log(myRegExp.test('abc'));
 console.log(typeof myRegExp);
 //3.使用字面量的方式更加简单,使用构造函数的创建
 //更加灵活。
 //4.创建一个正则表达式,检查字符中是否有a或b
 myRegExp=/a|b/;
 console.log(myRegExp.test('cd'));
 console.log(myRegExp.test('a'));
 console.log(myRegExp.test('b'));
 //5.创建字符串中检查是否包含字母
 //[]里的内容也是或的关系
 //[ab]==a|b
 //[a-z]表示a到z,表示任意的小写字母都可以
 //[A-z]表示任意字母,不区分大小写
 myRegExp=/[a-z]/;
 console.log(myRegExp.test('b'));
 //6.是否包含abc或adc或aec
 myRegExp=/a[bde]c/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('afc'));
 //7.[^]除了
 myRegExp=/[^ab]/;
 console.log(myRegExp.test('a'));
 console.log(myRegExp.test('c'));
 //8.[0-9]任意数字
 myRegExp=/[0-9]/;
 console.log(myRegExp.test('1'));
 console.log(myRegExp.test('c'));
 
(5)字符串与正则相关的方法
//字符串与正则相关的方法
 var checkStr='1ab2c3d4e5';
 //split()
 //1.将字符串拆分为数组
 var myArray=checkStr.split('c');
 console.log(myArray);
 //2.实现根据任意字母拆分
 //需要在方法中传递正则表达式
 //这种拆分方法更加灵活
 myArray=checkStr.split(/[A-z]/);
 console.log(myArray);
 //search()
 //1.可以搜索字符串是否包含指定内容
 //2.如果搜索到指定内容,则会返回第一次出现的索引
 //如果没有搜索到返回-1。
 //它可以接受一个正则表达式作为参数,然后根据正则
 //表达式去检索字符串
 var str='Hello abc';
 var myResult=str.search('abc');
 console.log(myResult);
 //如想搜索abc或aec或afc
 str='Hello abc aec afc';
 myResult=str.search(/a[bef]c/);
 console.log(myResult);
 //match()
 //1.可以根据正则表达式,从一个字符串中将符合条件的
 //提取出来,比如找出所有的字母
 //2.默认情况下match只会找到第一个,可以让正则表达式
 //开启全局模式g,可以全部匹配。
 //当然可以为一个正则表达式设置多个匹配模式,
 //顺序不重要如/XXXX/ig /XXX/gi
 //匹配到多个返回的是一个数组。
 str='1a2b3c4d5af6ea7agABC';
 myResult=str.match(/[A-z]/g);
 console.log(myResult);
 //replace()
 //1.可以将字符串中指定的内容替换为新的内容
 //2.两个参数,第一个是被替换的内容,第二个是新的内容
 myResult=str.replace(/a/ig,'X');
 console.log(myResult);
 myResult=str.replace(/[A-z]/ig,'X');
 console.log(myResult);
 
(6)正则表达式语法
//语法
 //创建一个正则表达式检查字符串是否有aaa
 var myRegExp=/aaa/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('aaa'));
 //如果检测3000个a怎么写呢?
 //量词
 //1.所以就有量词的表达
 //2.a{3}代表a连续出现3次
 myRegExp=/a{3}/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('aaa'));
 //3.量词只对它前边的一个内容起作用
 //如果ab连续出现几次需要(ab){3}来表达
 myRegExp=/(ab){3}/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('ababab'));
 //4.一个字母出现1-N次
 //b{1,3}
 myRegExp=/ab{1,3}c/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('abbbc'));
 console.log(myRegExp.test('abbbbc'));
 //5.一个字母至少出现1次
 //b+,相当于{1,}
 myRegExp=/ab+c/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('ac'));
 //* 表示一个或多个,相当于{0,}
 //? 表示0个或1个{0,1}
 //6.检查一个字符串是否以a开头
 // ^表示开头
 myRegExp=/^a/;
 console.log(myRegExp.test('bac'));
 console.log(myRegExp.test('ac'));
 //7. a$ 表示以a结尾
 myRegExp=/a$/;
 console.log(myRegExp.test('abc'));
 console.log(myRegExp.test('cba'));
 //8.^a$ 表示以此a为开头,又要以此a结尾
 //也就是只能有一个a
 myRegExp=/^a$/;
 console.log(myRegExp.test('a'));
 //9.以a开头以a结尾
 myRegExp=/^a[A-z]{1,}a$/;
 console.log(myRegExp.test('abcdafdsafa'));
 //10.用正则表达式检查是否为合法的手机号
 //手机号的规则:
 //(1)第一位以1开头
 //(2)第二位3-9任意数字
 //(3)三位任意数字9个
 //(4)分开写^1 [3-9] [0-9]{9}$
 myRegExp=/^1[3-9][0-9]{9}$/;
 console.log(myRegExp.test('13703619524'));
 console.log(myRegExp.test('11703619524'));
 console.log(myRegExp.test('117-3619524'));
 
 
//语法二
 //检查字符串中是否含义.
 //1.点.表示任意字符
 //2.如何检测点呢? 需要用转义字符
 // .即可
 //3.其他的也是同样的道理,如检查等也需要转义
 //4.注意使用构造函数时候,由于他的参数是字符串
 //必须使用来代替转义
 var myRegExp=/./;
 console.log(myRegExp.test('avc.daf'));
 console.log(myRegExp.test('121212'));
 // w W d...
 // w表示任意字母、数字
 // W表示除了字母、数字
 // d表示任意的数字[0-9]
 // D除了数字[^0-9]
 // s空格
 // S除了空格
 // 单词边界
 // B除了单词边界
 myRegExp=/child/;
 //非child单词不匹配
 console.log(myRegExp.test('children'));
 console.log(myRegExp.test('child'));
 //接受一个用户的输入,去除掉其中的空格
 //只去两遍的,不去中间的空格
 var userInput=prompt('请输入你的用户名: ');
 userInput=userInput.replace(/^s{0,}|s{0,}$/g,'');
 console.log(userInput);
 
(7)电子邮件的正则
//电子邮件
 //1.任意的字母数字下划线.任意的字母数字下划线
 //2.@符
 //3.任意字母数字
 //4. .任意字母(2-5位)
 //5.预写w{3,} (.w{1,}){0,} @ [A-z0-9]{0,} (.[A-z]{2,5}){1,2}
 var myRegExp=/^w{3,}(.w{1,}){0,}@[A-z0-9]{0,}(.[A-z]{2,5}){1,2}$/;
 console.log(myRegExp.test('wdfgdzx@163.com'));
 console.log(myRegExp.test('weffadfadf'));
 
10.关于DOM
(1)概述
//宿主对象DOM与BOM
 //Document Object Model文档对象模型
 //1.文档 整个HTML网页文档
 //2.对象 对象表示将网页中的每一个部分都转换为一个对象
 //3.模型 使用模型来表示对象之间的关系,这样方便我们获取对象
 //就是体现节点与节点之间的关系的
 //4.节点:Node是构成网页的最基本的组成部分
 //常用节点:文档节点(HTML文档)、元素节点(HTML标签)、属性节点(元素的属性)、文本节点(HTML中的文本内容)
 //5.节点的属性
 //(1)nodeName
 //(2)nodeType
 //(3)nodeValue
 //6.一句话DOM就是用来操作网页的
 //浏览器已经为我们提供了文档节点,这个对象是window属性
 //可以在页面中直接使用,文档节点代表的是整个网页
 console.log(document);
 //获取到button对象
 var myButton=document.getElementById('myButton');
 console.log(myButton);
 //修改按钮的文字
 myButton.innerHTML='修改后的按钮...';
 
(2)事件
//事件
  //1.就是文档或浏览器窗口中发生的一些特定的交互瞬间
  //2.比如按钮的点击、窗口大小的改变、窗口的关闭...
  //3.最重要的是处理事件,需要设置对应的JS代码
  //4.这种在Html中写结构与行为耦合了,不推荐使用
  //5.使用下面的方法
  var myButton=document.getElementById('myButton');
  //绑定一个单击事件,而且进行了代码分离
 /* myButton.οnclick=function(){
      alert('不要点我...');
  };*/
  //绑定双击事件
  myButton.οndblclick=function(){
      alert('你还双击我');
  };
 
(3)文档的加载
//文档的加载
 var myButton=document.getElementById('myButton');
 myButton.οnclick=function(){
     alert('点我干什么呀');
 };
 //为什么JS不写在body的上面呢?
 //1.因为文档的加载是一行行按顺序加载的
 //2.如果JS写在上面,代码执行时页面还没有加载,所以会报错
 //3.所以JS代码一定要写在body的下面
 //4.如果非要写在上面有什么办法吗?
 //也就是等页面加载完毕后再执行JS
 //onload
 //会在整个页面加载完毕后再执行
 //为window绑定onload事件
 //这样可以确保代码执行时所有的DOM对象已经加载完毕
 window.οnlοad=function(){
     //这里就可以保证
     alert('Hello');
 };
 //最优化的方式还是把JS写在下面
 
(4)DOM查询
//DOM查询
 //1.通过Id
 //2.通过TagName
 //3.通过Name
 //查看#bj节点
 var bj=document.getElementById('bj');
 console.log(bj.innerHTML);
 //查找所有的li节点
 var allLi=document.getElementsByTagName('li');
 for(var i=0;i<allLi.length;i++){
     console.log(allLi[i].innerHTML);
 }
 //即是查询到的只有一个元素也会封装到数组中返回
 //查找name=gender的所有节点
 var allGender=document.getElementsByName('gender');
 for(var i=0;i<allGender.length;i++){
     //innerHTML获取标签内部的HTML代码的
     //像这种没有内部的,自结束标签没有意义
     //读取的时候直接.就可以了
     //读取class(因为是保留字)时需要用className
     console.log(allGender[i].value);
 }
 
(5)图片切换
//图片切换
 //点击按钮切换图片
 var up=document.getElementById('up');
 var down=document.getElementById('down');
 var img=document.getElementsByTagName('img');
 //因为是数组,就一个所以直接img[0]赋值
 img=img[0];
 //创建一个数组用来保存图片路径
 var imgArray=['siteJsCssTool/1.jpg','siteJsCssTool/2.jpg','siteJsCssTool/3.jpg'];
 //创建一个变量,来保存当前正在显示图片的索引
 var imgIndex=0;
 var imgInfo=document.getElementById('imgInfo');
 imgInfo.innerHTML="共"+imgArray.length+"图片,当前第"+(imgIndex+1)+"张";
 //切换图片其实就是修改src的属性
 up.οnclick=function(){
     if(imgIndex>0){
         imgIndex=imgIndex-1;
     }else{
         imgIndex=2;
     }
     imgInfo.innerHTML="共"+imgArray.length+"图片,当前第"+(imgIndex+1)+"张";
     img.src=imgArray[imgIndex];
 };
 down.οnclick=function(){
     if(imgIndex<2){
         imgIndex=imgIndex+1;
     }else{
         imgIndex=0;
     }
     imgInfo.innerHTML="共"+imgArray.length+"图片,当前第"+(imgIndex+1)+"张";
     img.src=imgArray[imgIndex];
 };
 
CSS
*{
     margin:0;
     padding:0;
 }
 #outer{
     width: 550px;
     margin:50px auto;
     padding:10px;
     background-color:yellowgreen;
     /*文本居中*/
     text-align: center;
 }
 
HTML
<div id="outer">
     <p id="imgInfo">一共3张图片,当前第1张</p>
     <img src="siteJsCssTool/1.jpg" alt="美女" width="530px"/>
     <button id="up">上一张</button>
     <button id="down">下一张</button>
 </div>
 
(6)获取子节点
//获取子节点
 //childNodes表示当前节点的所有子节点
 //firstChild表示当前节点的第一个子节点
 //lastChild表示当前节点的最后一个子节点
 //查找#city下所有li节点
 var city=document.getElementById('city');
 //注意这里是city. 不是document. !!!
 var cityLi=city.getElementsByTagName('li');
 for(var i=0;i<cityLi.length;i++){
     //console.log(cityLi[i].innerHTML);
 }
 //返回#city的所有子节点
 var cityAllChild=city.childNodes;
 for(var i=0;i<cityAllChild.length;i++){
     //一共9个,有4个li对象,5个文本Text对象
     //DOM文档中间的空白,也会被当成文本对象
     console.log(cityAllChild[i].innerHTML);
 }
 var cityChildren=city.children;
 //这里获取的是所有的子元素
 for(var i=0;i<cityChildren.length;i++){
     console.log(cityChildren[i].innerHTML);
 }
 
(7)父节点与兄弟节点
//父节点与兄弟节点
 //定义一个函数,为指定元素绑定单击响应函数
 //fun表示事件的回调函数
 function myFunctionClick(idStr,myFunction){
     var myButton=document.getElementById(idStr);
     myButton.οnclick=myFunction;
 }
 myFunctionClick('myButton',function(){
    console.log("我是第0个按钮...");
 });
 /*myFunctionClick('myButton1',function(){
     console.log("我是第1个按钮...");
 });*/
 myFunctionClick('myButton1',function(){
     var bj=document.getElementById('bj');
     var parentNode=bj.parentNode;
     console.log(parentNode.innerHTML);
     console.log(parentNode.innerText);
 });
 //innerText会自动讲html标签去除
 //previousSibling前一个兄弟节点(也可能获取到空白文本)
 //previousElementsSibling获取前一个兄弟元素(不会获取到空白文本)
 //读取指定id的value属性值
 var myText=document.getElementById('myText');
 console.log(myText.value);
 
(7)全选实现
//全选
 //1.点击全选按钮,四个多选框全都被选中
 //2.要熟练的使用文档查属性
 var allOrNo=document.getElementById('allOrNo');
 var allButton=document.getElementById('allButton');
 allButton.οnclick=function(){
     //设置四个多选框为选中状态
     //获取这四个多选框
     var chooseItems=document.getElementsByName('chooseItems');
     for(var i=0;i<chooseItems.length;i++){
         chooseItems[i].checked=true;
     }
     allOrNo.checked=true;
 };
 var noButton=document.getElementById('noButton');
 noButton.οnclick=function(){
     //设置四个多选框为选中状态
     //获取这四个多选框
     var chooseItems=document.getElementsByName('chooseItems');
     for(var i=0;i<chooseItems.length;i++){
         chooseItems[i].checked=false;
     }
     allOrNo.checked=false;
 };
 var reverseButton=document.getElementById('reverseButton');
 reverseButton.οnclick=function(){
     //设置四个多选框为选中状态
     //获取这四个多选框
     var chooseItems=document.getElementsByName('chooseItems');
     allOrNo.checked=true;
     for(var i=0;i<chooseItems.length;i++){
         /*if(chooseItems[i].checked==true){
             chooseItems[i].checked=false;
         }else if(chooseItems[i].checked==false){
             chooseItems[i].checked=true;
         }*/
         //可以进一步的优化为下面代码
         chooseItems[i].checked=!chooseItems[i].checked;
         if(!chooseItems[i].checked){
             allOrNo.checked=false;
         }
     }
 };
 //提交按钮
 //点击按钮以后,讲所有选中的多选框的value属性值弹出
 var sendButton=document.getElementById('sendButton');
 sendButton.οnclick=function(){
     var chooseItems=document.getElementsByName('chooseItems');
     for(var i=0;i<chooseItems.length;i++){
         if(chooseItems[i].checked){
             console.log(chooseItems[i].value);
         }
     }
 };
 //全选全部选多选框
 //为allOrNo绑定单击事件
 allOrNo.οnclick=function(){
     var chooseItems=document.getElementsByName('chooseItems');
     for(var i=0;i<chooseItems.length;i++){
         //在事件响应函数中,事件是给谁绑定的
         //this就是谁
         chooseItems[i].checked=this.checked;
     }
 }
 //四个多选框与allOrNo状态实现同步
 var chooseItems=document.getElementsByName('chooseItems');
 for(var i=0;i<chooseItems.length;i++){
     chooseItems[i].οnclick=function(){
         //上来就是全选
         allOrNo.checked=true;
         //判断四个多选框是否全选
         for(var j=0;j<chooseItems.length;j++){
             //只要有一个没选中则不是全选
             if(!chooseItems[j].checked){
                 allOrNo.checked=false;
             }
         }
     };
 }
 
(8)DOM查询剩余方法
//获取body标签
 var body=document.getElementsByTagName('body')[0];
 console.log(body);
 //也可以使用document直接获取
 body=document.body;
 console.log(body);
 //document.documentElement HTML页面
 //document.all 所有元素
 //document.getElementsByClassName() 也是数组,不支持IE8
 //document.querySelector('') 单个的
 //document.querySelectorAll('') 这个返回的是数组
 //可以用来选择class为''的元素或元素集合
 
(9)DOM增删改查
//DOM增删改的操作
  //appendChild() 把新节点添加到指定的节点
  //1.创建一个广州节点,添加到#city下
  //创建广州节点<li>广州</li>
  //创建<li>元素节点
  //document.createElement()可以创建元素节点对象
  //他需要一个标签名作为参数,会根据该标签名创建元素节点对象
  //并将创建好的对象作为返回值返回
 /* var myLi=document.createElement('li');
  //创建文本节点
  //需要一个文本内容作为参数
  var myText=document.createTextNode('广州');
  //将广州text设置为li的节点
  //appendChild()可以向父节点中添加新的子节点
  myLi.appendChild(myText);
  //添加到city下面
  var city=document.getElementById('city');
  city.appendChild(myLi);*/
 
  //2.将广州节点插入到#bj前面
  //一样的步骤
  /*var myLi=document.createElement('li');
  var myText=document.createTextNode('广州');
  myLi.appendChild(myText);
  var bj=document.getElementById('bj');
  //insertBefore()在指定的子节点前面插入新的子节点
  //父节点.insertBefore(新节点,旧节点)
  var city=document.getElementById('city');
  city.insertBefore(myLi,bj);*/
 
  //3.使用广州节点替换北京节点
 /* var myLi=document.createElement('li');
  var myText=document.createTextNode('广州');
  myLi.appendChild(myText);
  var bj=document.getElementById('bj');
  var city=document.getElementById('city');
  //replaceChild()使用指定的子节点替换已有的子节点
  city.replaceChild(myLi,bj);*/
 
  //4.删除北京节点
  /*var bj=document.getElementById('bj');
  var city=document.getElementById('city');
  //removeChild()可以删除一个子节点
  city.removeChild(bj);*/
  //如果通过北京子节点自己删也可以
  /*var bj=document.getElementById('bj');
  bj.parentNode.removeChild(bj);*/
 
  //5.修改#bj内的HTML代码
  /*var bj=document.getElementById('bj');
  bj.innerHTML='西安';*/
 
  //6.在原来的基础上加上广州
  var city=document.getElementById('city');
  //city.innerHTML=city.innerHTML+"<li>广州</li>";
  //city.innerHTML="<li>广州</li>"+city.innerHTML;
  //这种方式更简单,更直接,缺点是原来绑定的方法可能
  //被删除,所以"强烈建议"使用如下方式
  var myLi=document.createElement('li');
  myLi.innerHTML='广州';
  city.appendChild(myLi);
 
(10)DOM增删改训练
//添加删除记录练习
 //获取所有的超链接,删除功能
 var allHref=document.getElementsByTagName('a');
 //为每个超链接绑定一个单击响应函数
 for(var i=0;i<allHref.length;i++){
     allHref[i].οnclick=function(){
         //点击超链接后需要删除对应行
         //这里点击哪个超链接 this就是哪个
 
         var myTr=this.parentNode.parentNode;
         var name=myTr.getElementsByTagName('td')[0].innerHTML;
         //优化个提示
         var flag=confirm("确定要删除"+name+"吗?");
         if(flag){
             //自删除
             myTr.parentNode.removeChild(myTr);
         }
         //默认是跳转的,我们不希望它跳转
         //return false可以取消默认跳转
         return false;
     }
 }
 //添加功能
 var addEmployee=document.getElementById('addEmployee');
 addEmployee.οnclick=function(){
     //获取用户填写的信息
     var tempName=document.getElementById('Name');
     var tempEmail=document.getElementById('Email');
     var tempSalary=document.getElementById('Salary');
     //需要将获取到信息保存到tr中
     //比较麻烦的方法
     var tr=document.createElement('tr');
     var tdName=document.createElement('td');
     var tdEmail=document.createElement('td');
     var tdSalary=document.createElement('td');
     var tdHref=document.createElement('td');
     //创建一个a元素
     var a=document.createElement('a');
     var nameText=document.createTextNode(tempName.value);
     var emailText=document.createTextNode(tempEmail.value);
     var salaryText=document.createTextNode(tempSalary.value);
     var deleteText=document.createTextNode("Delete");
     //拼接子节点
     tdName.appendChild(nameText);
     tdEmail.appendChild(emailText);
     tdSalary.appendChild(salaryText);
     a.appendChild(deleteText);
     a.href='#';
     //还可以把这段函数提出来,放到外面共用
     a.οnclick=function(){
         var myTr=this.parentNode.parentNode;
         var name=myTr.getElementsByTagName('td')[0].innerHTML;
         var flag=confirm("确定要删除"+name+"吗?");
         if(flag){
             myTr.parentNode.removeChild(myTr);
         }
         return false;
     };
     tdHref.appendChild(a);
     //将td添加到tr中
     tr.appendChild(tdName);
     tr.appendChild(tdEmail);
     tr.appendChild(tdSalary);
     tr.appendChild(tdHref);
     //把tr添加到table中
     var employeeTable=document.getElementById('employeeTable');
     //获取tbody
     var tbody=employeeTable.getElementsByTagName('tbody')[0];
     tbody.appendChild(tr);
 }
 
使用简化的方法操作:
//添加删除记录练习
 //获取所有的超链接,删除功能
 var allHref=document.getElementsByTagName('a');
 //为每个超链接绑定一个单击响应函数
 for(var i=0;i<allHref.length;i++){
     allHref[i].οnclick=function(){
         //点击超链接后需要删除对应行
         //这里点击哪个超链接 this就是哪个
         var myTr=this.parentNode.parentNode;
         var name=myTr.getElementsByTagName('td')[0].innerHTML;
         //优化个提示
         var flag=confirm("确定要删除"+name+"吗?");
         if(flag){
             //自删除
             myTr.parentNode.removeChild(myTr);
         }
         //默认是跳转的,我们不希望它跳转
         //return false可以取消默认跳转
         return false;
     }
 }
 //添加功能
 var addEmployee=document.getElementById('addEmployee');
 addEmployee.οnclick=function(){
     //获取用户填写的信息
     var tempName=document.getElementById('Name');
     var tempEmail=document.getElementById('Email');
     var tempSalary=document.getElementById('Salary');
     var tr=document.createElement('tr');
     //设置tr中的内容
     tr.innerHTML="<td>"+tempName.value+"</td>"+
         "<td>"+tempEmail.value+"</td>"+
         "<td>"+tempSalary.value+"</td>"+
         "<td><a href='#'>Delete</a></td>";
     //获取a元素,为其绑定单击事件
     var a=tr.getElementsByTagName('a')[0];
     a.οnclick=function(){
         var myTr=this.parentNode.parentNode;
         var name=myTr.getElementsByTagName('td')[0].innerHTML;
         var flag=confirm("确定要删除"+name+"吗?");
         if(flag){
             myTr.parentNode.removeChild(myTr);
         }
         return false;
     };
     //把tr添加到table中
     var employeeTable=document.getElementById('employeeTable');
     //获取tbody
     var tbody=employeeTable.getElementsByTagName('tbody')[0];
     tbody.appendChild(tr);
 }
 
(11)a的索引问题
//a的索引问题
 var allHref=document.getElementsByTagName('a');
 //为每个超链接绑定一个单击响应函数
 for(var i=0;i<allHref.length;i++){
     alert('for循环正在执行...'+i);
     allHref[i].οnclick=function(){
         //这里为什么不相等呢?
         //因为i的值 i的值已经恒定为2了
         //因为for循环会先执行
         //而响应函数会在超链接点击时才执行,所以for
         //循环早已经执行完毕了
         //所以i一直为最大值了
         alert(i);
         alert(allHref[i]==this);
     }
 }
 
(12)操作内联样式
//操作内联样式
 //点击按钮后,修改box1的大小
 var myButton=document.getElementById('myButton');
 var box1=document.getElementById('box1');
 myButton.οnclick=function(){
     //修改box1的样式
     box1.style.width='500px';
     box1.style.height='500px';
     //如果样式名中含有-,这种是不合法的
     //需要将这种样式修改为驼峰命名法
     //如果实在忘记了,去看文档即可
     box1.style.backgroundColor='yellow';
     //通过这种方法修改的是内联样式
     //所以修改了立刻就生效了
     //但是千万不要写!important,则此时是最高的优先级
     //JS修改也无法改变。所以尽量不要这么使用
 };
 var myButton1=document.getElementById('myButton1');
 myButton1.οnclick=function(){
     //通过style属性读取的也是内联样式
     //所以如果上来默认点击会获取到打印出空
     //那么如何读取非内联样式呢?看后面的知识
     alert(box1.style.width);
     alert(box1.style.height);
     alert(box1.style.backgroundColor);
 
 };
 
(13)操作元素样式
//操作元素样式
 var myButton=document.getElementById('myButton');
 var box1=document.getElementById('box1');
 myButton.οnclick=function(){
     //读取当前样式
     //语法 元素.currentStyle.样式名,它可以用来读取当前显示的样式如果但前样式没有设置样式,则获取它的默认值
     //currentStyle只有IE浏览器支持,其他浏览器都不支持
     //alert(box.currentStyle.width);
     //在其他浏览器中可以使用getComputedStyle()这个方法来获取当前的样式,这个方法是window方法可以直接使用需要有两个参数第一个,需获取样式的元素。第二个,可以传递一个伪元素,一般都是null
     //需要两个参数1.获取样式的元素2.传递一个伪元素,一般传null
     //返回的对象封装了当前元素对应的样式
     //但是该方法不支持IE8及以下浏览器
     //var box1Style=getComputedStyle(box1,null);
     //alert(box1Style.width+"---"+box1Style.color);
     //通过以上两种方式都是只读的,如果要修改必须通过style属性
     alert(getStyle(box1,'width'));
 };
 //定义一个函数,用来获取指定元素的当前样式
 //元素,样式名
 function getStyle(myObject,name){
     //正常浏览器
     if(window.getComputedStyle){
         var myObjectStyle=getComputedStyle(myObject,null);
         return myObjectStyle[name];
     }else{
         //IE8的方式
         return myObject.currentStyle[name];
     }
 }
 
(14)其他样式相关的属性
JS部分
------------------------------
//其他样式属性操作
 var box1=document.getElementById('box1');
 var box2=document.getElementById('box2');
 var myButton=document.getElementById('myButton');
 myButton.οnclick=function(){
     //clientWidth
     //clientHeight
     //包括宽度/高度+内外边距padding
     //这些属性都是不带px,返回都是一个数字,可以直接进行计算
     //获取元素的宽度与高度,包括内容区和内边距
     //只能读取不能修改
     //alert("可见宽度:"+box1.clientWidth);
     //alert("可见高度:"+box1.clientHeight);
     //下面的这两个属性包括了内容区的高度/宽度
     //alert("元素宽度:"+box1.offsetWidth);
     //alert("元素高度:"+box1.offsetHeight);
     //offsetParent
     //获取当前元素的定位父元素
     //主要看外层元素是否开启相对定位relative
     //style="position:'relative';"
     //var myOffsetParent=box1.offsetParent;
     //alert("定位的父元素:"+myOffsetParent);
     //offsetLeft
     //相对于定位元素的水平偏移量
     //offsetTop
     //相对于定位元素的垂直偏移量
     //alert("水平偏移:"+box1.offsetLeft);
     //alert("垂直偏移:"+box1.offsetTop);
     //scrollHeight/scrollWidth
     //滚动高度,不现实的部分也计算
     //alert("滚动高度:"+box2.scrollHeight);
     //alert("滚动宽度:"+box2.scrollWidth);
     //scrollTop/scrollLeft
     alert("滚动条左边偏移量:"+box1.scrollLeft);
     alert("滚动条上下偏移量:"+box1.scrollTop);
     alert(box1.clientHeight);
 }
 //当垂直滚动条滚动到底时表单项可用
 //获取info的p元素
 var myInfo=document.getElementById('info');
 //为info绑定一个滚动条动态的事件
 var myInputArray=document.getElementsByTagName('input');
 myInfo.οnscrοll=function(){
     //检查是否垂直滚动条滚动到底
     if(myInfo.scrollHeight-myInfo.scrollTop==
         myInfo.clientHeight){
         //设置禁用的表单项可用
         //disabled属性可以设置一个元素是否禁用
         //如果设置为true则元素禁用,如果设置为false则元素可用
         myInputArray[0].disabled=false;
         myInputArray[1].disabled=false;
     }
 }
 
CSS部分
-------------------------------
#box1{
     width: 280px;
     height: 200px;
     background-color: red;
    /* 自适应,会出现滚动条*/
     overflow: auto;
 }
 #box2{
     width: 460px;
     height: 500px;
     background-color: #b7eb8f;
 }
 #info{
     width: 280px;
     height: 100px;
     background-color: darkolivegreen;
     overflow: auto;
 }
 
HTML部分
---------------------------
<h1>JS</h1>
 <!--主题部分-->
 <button id="myButton">点我一下</button>
 <hr/>
 <div id="box1">
     <div id="box2">
 
     </div>
 </div>
 <h1>亲爱的用户,欢迎注册</h1>
 <p id="info">
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
     必须仔细阅读<br/>
 </p>
 <!--如果为表单项添加disabled="disabled" 则表单项将变成不可用的-->
 <input type="checkbox" disabled="disabled"/>我已经仔细阅读,同意遵守!
 <input type="submit" value="注册" disabled="disabled"/>
 
11.事件部分
(1)事件对象
JS:
//事件对象
 var areaDiv=document.getElementById('areaDiv');
 var showMsg=document.getElementById('showMsg');
 //onmousemove
 //该事件在 鼠标在元素中移动时被触发
 //事件对象
 //1、当事件的响应函数被触发时,浏览器每次都会将一个事件对象
 //作为实参传递进响应函数。
 //2、这个对象封装了当前时间的一切信息,比如鼠标的坐标,
 //键盘的那个按键被按下,鼠标滚轮的移动方向...
 areaDiv.οnmοusemοve=function(myEvent){
     //myEvent=event||window.event
     //alert('想屁吃');
     //在showMsg中显示鼠标的坐标
     if(myEvent){
         var tempX=myEvent.clientX;
         var tempX=myEvent.clientY;
     }else{
         //在IE8及以下浏览器中要用
         var tempX=window.event.clientX;
         var tempY=window.event.clientY;
     }
     showMsg.innerHTML="X坐标:"+tempX+",Y坐标:"+tempX;
 };
 
CSS:
#areaDiv{
     width: 500px;
     height: 100px;
     border: solid 1px;
 }
 #showMsg{
     width: 500px;
     height: 50px;
     border: solid 1px;
 }
 
HTML部分两个DIV,比较简单。
(2)DIV与鼠标同动
//事件的冒泡
 var mySpan=document.getElementById('mySpan');
 var box1=document.getElementById('box1');
 mySpan.οnclick=function(myEvent){
     alert('我是span的单击响应函数...');
     //取消冒泡
     myEvent.cancelBubble=true;
     //同时可以联想到移动DIV时,可以不让移动到其他DIV的内部
 };
 box1.οnclick=function(){
     alert('我是box1的单击响应函数...');
 };
 document.body.οnclick=function(){
     alert('我是body的单击响应函数...');
 };
 //1、点击mySpan
 //其余的box1与document的点击也都被触发了
 //所谓"冒泡"就是后代元素事件被触发时,祖先元素
 //的相同事件也会被触发。
 //2、"冒泡的事件"
 //3、大部分冒泡都是有用的,如果不需要可以用时间对象取消
 
(3)事件的委派
//事件的委派
  //为每个超链接绑定一个单击响应函数
 /* var aArray=document.getElementsByTagName('a');
  //遍历
  for(var i=0;i<aArray.length;i++){
      aArray[i].οnclick=function(){
          alert('我是a的单击响应函数');
      };
  }*/
  var myButton=document.getElementById('myButton');
  var myUl=document.getElementById('myUl');
  myButton.οnclick=function(){
      var li=document.createElement('li');
      li.innerHTML="<a href="#" class="myLink">新建的超链接</a>";
      myUl.appendChild(li);
  };
  //1、为每个超链接都绑定一个单击响应函数
  //这种操作比较麻烦,而且这些操作只能为已有的超链接设置事件
  //新添加的时间必须重新绑定
  //2、我们希望只绑定一次时间,即可应用到多个元素上
  //即是元素是动态的
  //这就是事件的"委派"
  //3、绑定给祖先元素单击事件,这样子元素就可以冒泡到
  //祖先元素,利用冒泡可以减少事件绑定。
  myUl.οnclick=function(myEvent){
      //1、如果触发事件对象是我们期望的元素则我们执行
      //否则不执行。
      //2、target返回触发事件对象的元素
      myEvent=myEvent||window.event;
      if(myEvent.target.className=='myLink'){
          alert('我是ul的单击绑定函数');
      }
  };
 
HTML部分:
<button id="myButton">添加超链接</button>
 <ul id="myUl">
     <li><a href="#" class="myLink">超链接1</a></li>
     <li><a href="#" class="myLink">超链接2</a></li>
     <li><a href="#" class="myLink">超链接3</a></li>
 </ul>
 
CSS部分:
#myUl{
     background-color: #4d5669;
 }
 
(4)事件的绑定
//事件的绑定
 var myButton=document.getElementById('myButton');
 myButton.οnclick=function(){
     alert("第一个函数...");
 };
 //如果绑定第二个函数
 //1、使用对象.事件=函数的形式
 //只能同时为一个元素的事件绑定一个相应函数
 //不能绑定多个,如果绑定了多个,则后边会覆盖掉前面的
 //2、addEventListener()
 //这个方法也可以为元素绑定响应函数
 //参数
 //(1)事件的字符串,不要on
 //(2)回调函数,当事件触发时该函数会被调用
 //(3)是否在捕获阶段触发事件,需要一个布尔值,一般都传false
 //可以为一个元素的相同事件同时绑定多个响应函数,
 //当事件被触发时,会按照绑定顺序依次执行
 //3、当时这种方法不支持IE8及以下浏览器
 myButton.addEventListener('click',function(){
     alert('第二种方式绑定的函数1...')
 },false);
 myButton.addEventListener('click',function(){
     alert('第二种方式绑定的函数2...')
 },false);
 //IE8中要使用attachEvent()来进行绑定
 //myButton.attachEvent('onclick',function(){});
 //4、写个通用的绑定函数
 //addEventListener对应的this,是绑定事件的对象
 //attachEvent中的this,是window
 function bind(myObject,myEventStr,myCallback){
     //如果有这个方法则用,没有则用别的
     if(myObject.addEventListener){
         //谷歌等浏览器
         myObject.addEventListener(myEventStr,myCallback,false);
     }else{
         //IE8及以下
         myObject.attachEvent('on'+myEventStr,function(){
             //在匿名函数中调用回调函数
             myCallback.call(myObject);
             //这样做的目的就是统一this指向button对象
         });
     }
 }
 
(5)事件的传播
JS:----
//事件的传播
 var myDiv=document.getElementById('myDiv');
 var myDiv1=document.getElementById('myDiv1');
 var myDiv2=document.getElementById('myDiv2');
 //事件的传播网景和微软公司有不同的理解
 //1、微软公司认为事件应该是由内向外传播,也就是当前事件
 //触发时,应该先触发当前元素上的事件,然后再向祖先事件传播
 //,也就是从内向外,按照冒泡事件执行。
 //2、网景公司认为事件应该是由外向内传播的,也就是先触发
 //祖先元素事件,然后再向内传播给后代元素。
 //3、最后w3c综合两个公司的方案,将事件传播分为三个阶段
 //(1)捕获阶段,由祖先到目标元素进行事件的捕获,默认此时不会触发事件
 //(2)目标阶段,事件捕获到目标元素,开始在目标元素上执行事件
 //(3)冒泡阶段,事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
 //4、如果希望在捕获阶段就触发事件,可以将addEventListener()第三个参数
 //设置为true。刚好和目前的执行相反。一般我们不会使用。
 //所以此参数一般都设置为false。
 bind(myDiv,'click',function(){
     alert('我是myDiv的响应函数');
 });
 bind(myDiv1,'click',function(){
     alert('我是myDiv1的响应函数');
 });
 bind(myDiv2,'click',function(){
     alert('我是myDiv2的响应函数');
 });
 function bind(myObject,myEventStr,myCallback){
     //如果有这个方法则用,没有则用别的
     if(myObject.addEventListener){
         //谷歌等浏览器
         myObject.addEventListener(myEventStr,myCallback,false);//设置为true执行相反,一般都设置为false
     }else{
         //IE8及以下
         myObject.attachEvent('on'+myEventStr,function(){
             //在匿名函数中调用回调函数
             myCallback.call(myObject);
             //这样做的目的就是统一this指向button对象
         });
     }
 }
 
HTML------
<div id="myDiv">
     <div id="myDiv1">
         <div id="myDiv2">
 
         </div>
     </div>
 </div>
 
CSS----
#myDiv{
     width: 300px;
     height: 300px;
     background-color: #b7eb8f;
 }
 #myDiv1{
     width: 200px;
     height: 200px;
     background-color: #13c2c2;
 }
 #myDiv2{
     width: 100px;
     height: 100px;
     background-color: #2baee9;
 }
 
(6)拖拽
JS----
//拖拽
 //1.当鼠标在元素上按下时开始拖拽onmousedown
 //2.当鼠标移动时,被拖拽元素跟随鼠标移动onmousemove
 //3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup
 var myDiv1=document.getElementById('myDiv1');
 myDiv1.οnmοusedοwn=function(){
     //当鼠标移动时
     document.οnmοusemοve=function(myEvent){
         //当鼠标移动时,被拖拽元素跟随鼠标移动
         myEvent=myEvent||window.event;
         //获取坐标
         var leftX=myEvent.clientX;
         var topY=myEvent.clientY;
         //修改myDiv1的位置
         myDiv1.style.left=leftX+'px';
         myDiv1.style.top=topY+'px';
     };
     //当鼠标松开时
     document.οnmοuseup=function(){
         //松开时
         //取消移动函数
         document.οnmοusemοve=null;
         //但是这个时候,如果有个myDiv2,当两个div
         //重叠时会有问题,所以鼠标松开也是要给
         //document绑定
         document.οnmοuseup=null;
     };
 };
 
HTML-----
<div id="myDiv1">
 </div>
 <div id="myDiv2">
 </div>
 
CSS----
#myDiv1{
     width: 100px;
     height: 100px;
     background-color: #2baee9;
     position: absolute;
 }
 #myDiv2{
     width: 100px;
     height: 100px;
     background-color: red;
     position: absolute;
     left: 200px;
     top: 200px;
 }
 
鼠标所在位置的优化JS-------
//拖拽(2)
 //1.当鼠标在元素上按下时开始拖拽onmousedown
 //2.当鼠标移动时,被拖拽元素跟随鼠标移动onmousemove
 //3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup
 var myDiv1=document.getElementById('myDiv1');
 myDiv1.οnmοusedοwn=function(myEventTop){
     //div的偏移量鼠标.clientX-元素.offsetLeft
     //div的偏移量鼠标.clientY-元素.offsetTop
     var myOffsetLeft=myEventTop.clientX-myDiv1.offsetLeft;
     var myOffsetTop=myEventTop.clientY-myDiv1.offsetTop;
     //当鼠标移动时
     document.οnmοusemοve=function(myEvent){
         //当鼠标移动时,被拖拽元素跟随鼠标移动
         myEvent=myEvent||window.event;
         //获取坐标
         var leftX=myEvent.clientX-myOffsetLeft;
         var topY=myEvent.clientY-myOffsetTop;
         //修改myDiv1的位置
         myDiv1.style.left=leftX+'px';
         myDiv1.style.top=topY+'px';
     };
     //当鼠标松开时
     document.οnmοuseup=function(){
         //松开时
         //取消移动函数
         document.οnmοusemοve=null;
         //但是这个时候,如果有个myDiv2,当两个div
         //重叠时会有问题,所以鼠标松开也是要给
         //document绑定
         document.οnmοuseup=null;
     };
 };
 
拖拽封装成函数(myObject)-----------
//拖拽(3) 拖消失问题的解决
 //1.当鼠标在元素上按下时开始拖拽onmousedown
 //2.当鼠标移动时,被拖拽元素跟随鼠标移动onmousemove
 //3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup
 var myDiv1=document.getElementById('myDiv1');
 myDiv1.οnmοusedοwn=function(myEventTop){
     //div的偏移量鼠标.clientX-元素.offsetLeft
     //div的偏移量鼠标.clientY-元素.offsetTop
     var myOffsetLeft=myEventTop.clientX-myDiv1.offsetLeft;
     var myOffsetTop=myEventTop.clientY-myDiv1.offsetTop;
     //当鼠标移动时
     document.οnmοusemοve=function(myEvent){
         //当鼠标移动时,被拖拽元素跟随鼠标移动
         myEvent=myEvent||window.event;
         //获取坐标
         var leftX=myEvent.clientX-myOffsetLeft;
         var topY=myEvent.clientY-myOffsetTop;
         //修改myDiv1的位置
         myDiv1.style.left=leftX+'px';
         myDiv1.style.top=topY+'px';
     };
     //当鼠标松开时
     document.οnmοuseup=function(){
         //松开时
         //取消移动函数
         document.οnmοusemοve=null;
         //但是这个时候,如果有个myDiv2,当两个div
         //重叠时会有问题,所以鼠标松开也是要给
         //document绑定
         document.οnmοuseup=null;
     };
     //1.当我们拖拽网页中的内容时,浏览器会默认去搜索引擎中搜索内容
     //此时会导致拖拽功能的异常,这个是浏览器提供的默认行为
     //可以通过return false来取消这个行为
     //2.但是这个方法对IE8不起作用
     //方法setCapture(),土匪把下次所有的事件都揽到自己身上
     //myDiv1.setCapture();//只有IE支持,在谷歌中会报错
     //当鼠标松开时取消这个函数
     //所以需要加判断if(myDiv1.setCapture)...
     //myDiv1.releaseCapture(),这里也要加判断才执行
     return false;
 };
 //可以提炼为函数方法,专门绑定拖拽使用
 //不仅可以拖拽div也可以拖拽img只需要传对象就可以了
 
(7)滚轮的事件
//滚轮事件
 //滚轮可以改变div的高度
 var myDiv1=document.getElementById('myDiv1');
 //绑定滚轮事件onmousewheel
 //但是火狐不支持该属性
 //DOMMouseScroll来绑定该事件,而且必须通过
 //addEventListener()函数来绑定
 myDiv1.onmousewheel=function(myEvent){
     //判断鼠标滚轮滚动的方向
     //向上滚120 向下滚是-120
     //wheelDelta只看正负就可以了
     //wheelDelta这个属性火狐中也不支持
     //在火狐中是myEvent.detail
     if(myEvent.wheelDelta>0||myEvent.detail<0){
         //alert('向上滚');
         //box1变短
         if(myDiv1.clientHeight>10){
             myDiv1.style.height=myDiv1.clientHeight-10+'px';
         }
     }else{
         //alert('向下滚');
         myDiv1.style.height=myDiv1.clientHeight+10+'px';
     }
     //1.当滚轮滚动时,浏览器有滚动条,滚动条也会随之滚动
     //这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
     //2.使用addEventListener()方法绑定响应函数,取消默认行为时
     //不能使用return false
     //需要使用event来取消默认行为,火狐就是这样
     //IE8不支持,所以这里要加个判断
     if(myEvent.preventDefault){
         myEvent.preventDefault();
     }
     //if判断也可以用这种写法
     myEvent.preventDefault &&myEvent.preventDefault();
     return false;
 };
 //为火狐绑定
 bind(myDiv1,'DOMMouseScroll', myDiv1.onmousewheel);
 
 function bind(myObject,myEventStr,myCallback){
     //如果有这个方法则用,没有则用别的
     if(myObject.addEventListener){
         //谷歌等浏览器
         myObject.addEventListener(myEventStr,myCallback,false);//设置为true执行相反,一般都设置为false
     }else{
         //IE8及以下
         myObject.attachEvent('on'+myEventStr,function(){
             //在匿名函数中调用回调函数
             myCallback.call(myObject);
             //这样做的目的就是统一this指向button对象
         });
     }
 }
 
(8)键盘事件
//键盘事件
 //onkeydown按下 onkeyup松开
 //1.onkeydown如果一直按着某个键,会连续触发
 //2.当其连续触发时,第一次与第二次间隔稍微长点
 //其他的会非常快,这里是为了防止误操作。
 //这种设计是浏览器的设计。
 //3.onkeyup只会触发一次
 //键盘事件一般会绑定给获取到焦点的对象
 //或者是document
 var inputArray=document.getElementsByTagName('input');
 /*document.οnkeydοwn=function(myEvent){
     myEvent=myEvent||window.event;
     //可以通过keyCode获取按键编码
     console.log(myEvent.keyCode);
     //通过keyCode可以判断哪个键被按了
     if(myEvent.keyCode===13){
         console.log('你按的是回车键');
     }
     //判断ctrl/shift/alt+某个字母被按下
     //ctrlKey
     //shiftKey
     //altKey
     if(myEvent.keyCode===89&&event.ctrlKey){
         console.log('你按的是ctrl+y');
     }
     console.log('键盘被按下...');
 };
 document.οnkeyup=function(myEvent){
     myEvent=myEvent||window.event;
     console.log('键盘被松开...');
 };*/
 inputArray[0].οnkeydοwn=function(myEvent){
     myEvent=myEvent||window.event;
     //可以通过keyCode获取按键编码
     console.log(myEvent.keyCode);
     //通过keyCode可以判断哪个键被按了
     if(myEvent.keyCode===13){
         console.log('你按的是回车键');
     }
     //判断ctrl/shift/alt+某个字母被按下
     //ctrlKey
     //shiftKey
     //altKey
     if(myEvent.keyCode===89&&event.ctrlKey){
         console.log('你按的是ctrl+y');
     }
     console.log('键盘被按下...');
     //如果加上return false,则输出的内容不会到文本框中
     //可以使文本框中不能输入数字
     if(myEvent.keyCode>=48 && myEvent.keyCode<=57){
         return false;
     }
 };
 inputArray[0].οnkeyup=function(myEvent){
     myEvent=myEvent||window.event;
     console.log('键盘被松开...');
 };
 //让div根据按键方向移动上下左右键盘
 
(9)键盘移动DIV
//键盘移动DIV
 var myDiv1=document.getElementById('myDiv1');
 //定义速度
 var speed=10;
 document.οnkeydοwn=function(myEvent){
     myEvent=myEvent||window.event;
     console.log(myEvent.keyCode);
     //当用户按了ctrl以后速度加快
     if(myEvent.ctrlKey){
         speed=500;
         console.log('按下了加速'+speed);
     }
     switch (myEvent.keyCode) {
         case 37:
             console.log("左"+speed);
             myDiv1.style.left=myDiv1.offsetLeft-speed+'px';
             break;
         case 38:
             console.log("上"+speed);
             myDiv1.style.top=myDiv1.offsetTop-speed+'px';
             break;
         case 39:
             console.log("右"+speed);
             myDiv1.style.left=myDiv1.offsetLeft+speed+'px';
             break;
         case 40:
             console.log("下"+speed);
             myDiv1.style.top=myDiv1.offsetTop+speed+'px';
             break;
     }
 }
 
12.关于BOM
(1)Navigator
//BOM Navigator
 //提供了一组对象,用来完成对浏览器的操作
 //BOM对象有哪些
 //1.Window
 //代表的是整个浏览器的窗口,同时window也是网页中的全局对象
 //2.Navigator
 //代表当前浏览器的信息,通过该对象可以识别不同的浏览器
 //3.Location
 //代表浏览器的当前地址栏信息,通过它可以获取地址栏信息,
 //或者操作浏览器跳转页面
 //4.History
 //代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,
 //由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器
 //向前或者向后翻页,而且该操作只在当次访问时有效。
 //5.Screen
 //代表用户的屏幕的信息,通过该对象可以获取到用户显示器的相关
 //信息。
 //6.这些BOM对象都是在浏览器中作为Window对象属性保存的,
 //可以通过Windows对象来使用,也可以直接使用。
 /*console.log(window);
 console.log(navigator);
 console.log(location);
 console.log(history);*/
 //1.我们先看navigator
 //(1)由于历史原因,navigator对象中大部分属性都已经不能帮我识别浏览器了
 //一般我们只会使用userAgent(用户代理)来判断浏览器的信息。
 //userAgent是一个字符串,包含用来描述浏览器的信息的内容。
 //不同的浏览器会有不同的userAgent
 //谷歌:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36
 //2345:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36
 console.log("浏览器名称:"+navigator.userAgent);
 var myUserAgent=navigator.userAgent;
 if(/chrome/i.test(myUserAgent)){
     alert("你用的是谷歌浏览器...");
 }else if(/msie/i.test(myUserAgent)){
     alert("你用的是IE浏览器...");
     //IE11已经将微软和IE相关的标识去除了
     //所以我们基本不能通过userAgent来识别是否为IE了
 }
 //2.如果不能通过userAgent判断,可以通过一些浏览器中
 //特有的对象,来判断浏览器的信息。
 //比如ActiveXObject
 //只有IE里能打印出来
 //3."ActiveXObject" in window 这是检查一个对象里是否
 //包含某个属性。
 if("ActiveXObject" in window){
     alert("是IE浏览器");
 }else{
     alert("不是IE浏览器");
 }
 
(2)History
//History
 //1.可以用来操作浏览器向前或者向后翻页
 //2.length可以获取到当成访问的链接数量
 alert(history.length);
 var myButton=document.getElementById('myButton');
 myButton.οnclick=function(){
     //和浏览器的后退按钮一样
     history.back();
     //可以跳转到下一个页面,与前进按钮一样
     history.forward();
     //可以跳转到指定页面
     //1表示向前跳转一个页面,相当于forward
     //2表示向前跳转两个页面
     //-1是向后跳转一个页面,相当于back
     //-2是向后跳转两个页面
     history.go();
 }
 
(3)Location
//Location
 //1.该对象封装了浏览器的地址栏信息
 //2.可以获取当前页面的完整路径
 alert(location);
 var myButton=document.getElementById('myButton');
 myButton.οnclick=function(){
     location='https://www.baidu.com';
     //1.如果直接将location修改为一个相对路径或完整路径。
     //则页面直接跳转到该路径,而且会生成响应的历史记录
     //2.location还能获取端口号、服务器相关的方法
     //3.assign()跳转其他页面,与直接修改location一样
     //location.assign('https://www.baidu.com');
     //reload()重新加载当前页面,与刷新按钮一样
     //location.reload();
     //ctrl+F5可以强制清空页面缓存,与location.reload(true)效果一样
     //用新页面替换当前页面,只是不会生成历史记录。
     location.replace('https://www.baidu.com');
 };
 
(4)定时器
//定时器 Window对象
 //1.setInterval()定时调用
 //2.但是循环太快了
 //3.如果希望每间隔一段时间执行一次,可以使用定时调用
 //setInterval()
 var myCount=document.getElementById("myCount");
 //开启定时器,可以将函数每隔一段时间执行一次
 //参数(1)回调函数(2)每次调用间隔的时间ms
 var tempNum=1;
 var mySetInterval=setInterval(function(){
     myCount.innerHTML=tempNum++;
     //在达到11时就关闭定时执行器
     if(tempNum==11){
         clearInterval(mySetInterval);
     }
 },1000);
 //setInterval这个方法会返回一个Number类型的数据
 //1.clearInterval()用来关闭一个定时器
 //2.方法中需要一个定时器的标识作为参数,这样将关闭
 //标识对应的定时器。
 
(5)自动切换图片
var myImg=document.getElementById("myImg");
 var myButton=document.getElementById("myButton");
 var myButton1=document.getElementById("myButton1");
 var mySetInterval;
 myButton.οnclick=function(){
     //1.每点击一次按钮,就回开启一个定时器
     //如果点击十次,就回开启10个定时器了
     //这就导致图片切换速度切换过快,并且只能关闭
     //最后一个定时器。
     //2.所以在开启之前就把上一个关闭了
     clearInterval(mySetInterval);
     var tempNum=1;
     mySetInterval=setInterval(function(){
         myImg.src="siteJsCssTool/"+(tempNum++)+".jpg";
         if(tempNum==4){
             tempNum=1;
             //clearInterval(mySetInterval);
         }
     },1000);
 };
 myButton1.οnclick=function(){
     clearInterval(mySetInterval);
 };
 //1.clearInterval()可以接受任意参数
 //如果参数有效,则停止对应的定时器
 //如果不是有效标识,则什么都不做。
 
(6)通过定时器解决方块移动卡顿
//键盘移动DIV
 var myDiv1=document.getElementById('myDiv1');
 //定义速度
 var speed=10;
 var direction=0;
 //开启一个定时器,来控制div的移动
 setInterval(function(){
     switch (direction) {
         case 37:
             console.log("左"+speed);
             myDiv1.style.left=myDiv1.offsetLeft-speed+'px';
             break;
         case 38:
             console.log("上"+speed);
             myDiv1.style.top=myDiv1.offsetTop-speed+'px';
             break;
         case 39:
             console.log("右"+speed);
             myDiv1.style.left=myDiv1.offsetLeft+speed+'px';
             break;
         case 40:
             console.log("下"+speed);
             myDiv1.style.top=myDiv1.offsetTop+speed+'px';
             break;
     }
 },30)
 document.οnkeydοwn=function(myEvent){
     myEvent=myEvent||window.event;
     direction=myEvent.keyCode;
     console.log(myEvent.keyCode);
     //当用户按了ctrl以后速度加快
     if(myEvent.ctrlKey){
         speed=500;
         console.log('按下了加速'+speed);
     }else{
         speed=10;
     }
 }
 document.οnkeyup=function(){
     //设置方向为0
     direction=0;
 }
(7)延时调用
//1.延时调用
 var num=1;
 //定时调用
 /* setInterval(function(){
      console.log(num++);
  },3000);*/
 //延时调用
 //隔3秒以后再执行,"只会执行一次"
 var mySetTimeout=setTimeout(function(){
     console.log(num++);
     clearTimeout(mySetTimeout);
 },3000);
 //关闭延时调用
 //clearTimeout(mySetTimeout);
 //2.延时调用与定时调用实际上是可以互相代替的,
 //在开发者用的多的是定时调用。
 
(8)定时器的应用
//定时器的应用
 var myDiv1=document.getElementById("myDiv1");
 var myDiv2=document.getElementById("myDiv2");
 var myButton=document.getElementById("myButton");
 var myButton1=document.getElementById("myButton1");
 var myButton2=document.getElementById("myButton2");
 var myButton3=document.getElementById("myButton3");
 //1.点击按钮后,使box1向右移动(left值增大)
 //当两个div都在这个变量中保存setInterval就会出现
 //问题。
 //所以保存在各自的对象中
 //全局变量要慎用
 //var mySetInterval;
 myButton.οnclick=function(){
     move(myDiv1,'left',800,10,function(){
         move(myDiv1,'height',500,10,function(){
             move(myDiv1,'top',1500,10,function(){
                 move(myDiv1,'top',0,10,function(){
 
                 });
             });
         });
     });
 };
 myButton1.οnclick=function(){
     move(myDiv1,'width',500,10);
 };
 myButton2.οnclick=function(){
     move(myDiv2,800,10);
 };
 //提取一个可以执行简单动画的函数
 //正数向右移动,负数向左移动
 //attr执行动画的样式
 //callback,这个函数将会在我们的动画执行完毕以后执行
 
 //1.也可以直接把这两个函数放到JS文件中
 //2.然后在要引用的地方引用,直接把库拷贝过去就可以了
 function move(myObject,attr,target,speed,callback){
     //防止多次点击开启多个定时器的问题
     clearInterval(myObject.mySetInterval);
     //获取当前值
     var currentValue=parseInt(getStyle(myObject,attr));
     if(currentValue>target){
         //此时speed为负值
         speed=-speed;
     }
     //开启定时器,用来执行动画效果
     myObject.mySetInterval=setInterval(function(){
         //获取div1原理left值
         var oldValue=parseInt(getStyle(myObject,attr));
         //判断速度的正负值
 
         //在旧的基础上增加
         var newValue=oldValue+speed;
         //向左移动是否小于target
         //向右移动是否大于target
         if((speed<0&&newValue<target) || (speed>0&&newValue>target)){
             newValue=target;
         }
         //新值设置给div1
         myObject.style[attr]=newValue+'px';
         //到达目标关闭定时器
         if(newValue==target){
             clearInterval(myObject.mySetInterval);
             //动画执行完毕,调用回调函数
             if(callback){
                 callback();
             }
         }
     },30);
 }
 function getStyle(obj,name){
     if(window.getComputedStyle){
         return getComputedStyle(obj,null)[name];
     }else{
         return obj.currentStyle[name];
     }
 }
 
(9)轮播图
HTML:
<!--创建一个外部的div,来作为大的容器-->
 <div id="divOuter">
     <!--创建一个ul,用于放置图片-->
     <ul id="ulImageList">
         <li><img src="siteJsCssTool/1.jpg" /></li>
         <li><img src="siteJsCssTool/2.jpg" /></li>
         <li><img src="siteJsCssTool/3.jpg" /></li>
     </ul>
     <!--创建导航按钮-->
     <div id="divNavigator">
         <a href="#"></a>
         <a href="#"></a>
         <a href="#"></a>
     </div>
 </div>
 
CSS:
<style>
     *{
         margin:0;
         padding:0;
     }
     #divOuter{
         width: 572px;
         height: 696px;
         /* 居中*/
         margin:50px auto;
         /*设置背景颜色*/
         background-color:yellowgreen;
         /*设置padding*/
         padding:10px 0;
         /*开启相对定位*/
         position: relative;
         /* 裁剪溢出的内容*/
         overflow: hidden;
     }
     #ulImageList{
         /*去除项目符号*/
         list-style: none;
         /*  width: 1800px;*/
         /*开启绝对定位*/
         position: absolute;
         /*每向左移动572px,就会显示到下一张图片*/
         left:-572px;
     }
     /*设置图片中的li*/
     #ulImageList li{
         /*设置浮动*/
         float:left;
         /*设置上下外边距*/
         margin:0 10px;
     }
     #ulImageList img{
         width: 552px;
         height: 696px;
     }
     /*设置导航按钮*/
     #divNavigator{
         /* 开启绝对定位*/
         position: absolute;
         bottom:105px;
         /*设置left的值
         outer宽度572
         divNavigator宽度 25*3=75
         572-75=497/2=248.5 */
         /*left:248.5px;
         写死不能适应所有情况,所以通过js*/
 
     }
     #divNavigator a{
         width: 15px;
         height: 15px;
         background-color: red;
         /*设置超链接浮动*/
         float:left;
         /*设置左右外边距*/
         margin: 0 5px;
         /*设置透明*/
         opacity:0.5;
         /*兼容IE8的透明*/
         filter:alpha(opacity=50);
     }
     #divNavigator a:hover{
         background-color: black;
     }
 </style>
 
JS:
<script>
     //轮播图
     //设置
     var ulImageList=document.getElementById('ulImageList');
     //设置ulImageList的宽度
     var imageArray=document.getElementsByTagName('img');
     ulImageList.style.width=imageArray.length*572+'px';
     var divNavigator=document.getElementById('divNavigator');
     var divOuter=document.getElementById('divOuter');
     //设置divNavigator的left的值
     /*console.log(divOuter.offsetWidth);
       console.log(divNavigator.clientWidth);*/
     divNavigator.style.left=(divOuter.offsetWidth -divNavigator.offsetWidth)/2+'px';
     //获取所有的a标签
     var aArray=document.getElementsByTagName('a');
     //设置第一张默认为黑色
     aArray[0].style.backgroundColor='black';
 </script>
 
(10)点击切换图片
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 <div id="divOuter">
     <!--创建一个ul,用于放置图片-->
     <ul id="ulImageList">
         <li><img src="siteJsCssTool/1.jpg" /></li>
         <li><img src="siteJsCssTool/2.jpg" /></li>
         <li><img src="siteJsCssTool/3.jpg" /></li>
     </ul>
     <!--创建导航按钮-->
     <div id="divNavigator">
         <a href="#"></a>
         <a href="#"></a>
         <a href="#"></a>
     </div>
 </div>
 </body>
 <style>
     *{
         margin:0;
         padding:0;
     }
     #divOuter{
         width: 572px;
         height: 696px;
         /* 居中*/
         margin:50px auto;
         /*设置背景颜色*/
         background-color:yellowgreen;
         /*设置padding*/
         padding:10px 0;
         /*开启相对定位*/
         position: relative;
         /* 裁剪溢出的内容*/
         overflow: hidden;
     }
     #ulImageList{
         /*去除项目符号*/
         list-style: none;
         /*  width: 1800px;*/
         /*开启绝对定位*/
         position: absolute;
         /*每向左移动572px,就会显示到下一张图片*/
         left:-572px;
     }
     /*设置图片中的li*/
     #ulImageList li{
         /*设置浮动*/
         float:left;
         /*设置上下外边距*/
         margin:0 10px;
     }
     #ulImageList img{
         width: 552px;
         height: 696px;
     }
     /*设置导航按钮*/
     #divNavigator{
         /* 开启绝对定位*/
         position: absolute;
         bottom:105px;
         /*设置left的值
         outer宽度572
         divNavigator宽度 25*3=75
         572-75=497/2=248.5 */
         /*left:248.5px;
         写死不能适应所有情况,所以通过js*/
 
     }
     #divNavigator a{
         width: 15px;
         height: 15px;
         background-color: red;
         /*设置超链接浮动*/
         float:left;
         /*设置左右外边距*/
         margin: 0 5px;
         /*设置透明*/
         opacity:0.5;
         /*兼容IE8的透明*/
         filter:alpha(opacity=50);
     }
     #divNavigator a:hover{
         background-color: black;
     }
 </style>
 <script>
     //轮播图
     //设置
     var ulImageList=document.getElementById('ulImageList');
     //设置ulImageList的宽度
     var imageArray=document.getElementsByTagName('img');
     ulImageList.style.width=imageArray.length*572+'px';
     var divNavigator=document.getElementById('divNavigator');
     var divOuter=document.getElementById('divOuter');
     //设置divNavigator的left的值
     /*console.log(divOuter.offsetWidth);
       console.log(divNavigator.clientWidth);*/
     divNavigator.style.left=(divOuter.offsetWidth -divNavigator.offsetWidth)/2+'px';
     //获取所有的a标签
     var aArray=document.getElementsByTagName('a');
     //设置第一张默认为黑色
     aArray[0].style.backgroundColor='black';
     //点击超链接切换到指定的图片
     //1.点击第一个超链接,显示第一个图片...以此类推
     //2.为所有的超链接绑定单击响应函数
     var index=0;
     ulImageList.style.left=index*-572+'px';
     for(var i=0;i<aArray.length;i++){
         //为每一个超链接都添加一个onlyMark属性
         aArray[i].onlyMark=i;
         aArray[i].οnclick=function(){
             //获取点击超链接的索引,并将其设置为index
             //alert(this.onlyMark);
             index=this.onlyMark;
             //切换图片
             //1.第一张 0 0 第二张 1 -572 第三张2 -572*2
             //ulImageList.style.left=index*-572+'px';
             setA(aArray,index);
             move(ulImageList,"left",index*-572,20,function(){
 
             });
         };
     }
     //创建一个方法用来设置选中的a
     function setA(myArray,myIndex){
         for(var i=0;i<myArray.length;i++){
             //myArray[i].style.backgroundColor='red';
             //让内联样式生效
             myArray[i].style.backgroundColor='';
         }
         myArray[myIndex].style.backgroundColor='black';
     }
     function move(myObject,attr,target,speed,callback){
         //防止多次点击开启多个定时器的问题
         clearInterval(myObject.mySetInterval);
         //获取当前值
         var currentValue=parseInt(getStyle(myObject,attr));
         if(currentValue>target){
             //此时speed为负值
             speed=-speed;
         }
         //开启定时器,用来执行动画效果
         myObject.mySetInterval=setInterval(function(){
             //获取div1原理left值
             var oldValue=parseInt(getStyle(myObject,attr));
             //判断速度的正负值
 
             //在旧的基础上增加
             var newValue=oldValue+speed;
             //向左移动是否小于target
             //向右移动是否大于target
             if((speed<0&&newValue<target) || (speed>0&&newValue>target)){
                 newValue=target;
             }
             //新值设置给div1
             myObject.style[attr]=newValue+'px';
             //到达目标关闭定时器
             if(newValue==target){
                 clearInterval(myObject.mySetInterval);
                 //动画执行完毕,调用回调函数
                 if(callback){
                     callback();
                 }
             }
         },30);
     }
     function getStyle(obj,name){
         if(window.getComputedStyle){
             return getComputedStyle(obj,null)[name];
         }else{
             return obj.currentStyle[name];
         }
     }
 </script>
 
 </html>
 
(11)完成所有轮播图
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 <div id="divOuter">
     <!--创建一个ul,用于放置图片-->
     <ul id="ulImageList">
         <li><img src="siteJsCssTool/1.jpg" /></li>
         <li><img src="siteJsCssTool/2.jpg" /></li>
         <li><img src="siteJsCssTool/3.jpg" /></li>
         <li><img src="siteJsCssTool/1.jpg" /></li>
     </ul>
     <!--创建导航按钮-->
     <div id="divNavigator">
         <a href="#"></a>
         <a href="#"></a>
         <a href="#"></a>
     </div>
 </div>
 </body>
 <style>
     *{
         margin:0;
         padding:0;
     }
     #divOuter{
         width: 572px;
         height: 696px;
         /* 居中*/
         margin:50px auto;
         /*设置背景颜色*/
         background-color:yellowgreen;
         /*设置padding*/
         padding:10px 0;
         /*开启相对定位*/
         position: relative;
         /* 裁剪溢出的内容*/
         overflow: hidden;
     }
     #ulImageList{
         /*去除项目符号*/
         list-style: none;
         /*  width: 1800px;*/
         /*开启绝对定位*/
         position: absolute;
         /*每向左移动572px,就会显示到下一张图片*/
         left:-572px;
     }
     /*设置图片中的li*/
     #ulImageList li{
         /*设置浮动*/
         float:left;
         /*设置上下外边距*/
         margin:0 10px;
     }
     #ulImageList img{
         width: 552px;
         height: 696px;
     }
     /*设置导航按钮*/
     #divNavigator{
         /* 开启绝对定位*/
         position: absolute;
         bottom:105px;
         /*设置left的值
         outer宽度572
         divNavigator宽度 25*3=75
         572-75=497/2=248.5 */
         /*left:248.5px;
         写死不能适应所有情况,所以通过js*/
 
     }
     #divNavigator a{
         width: 15px;
         height: 15px;
         background-color: red;
         /*设置超链接浮动*/
         float:left;
         /*设置左右外边距*/
         margin: 0 5px;
         /*设置透明*/
         opacity:0.5;
         /*兼容IE8的透明*/
         filter:alpha(opacity=50);
     }
     #divNavigator a:hover{
         background-color: black;
     }
 </style>
 <script>
     //轮播图
     //设置
     var ulImageList=document.getElementById('ulImageList');
     //设置ulImageList的宽度
     var imageArray=document.getElementsByTagName('img');
     ulImageList.style.width=imageArray.length*572+'px';
     var divNavigator=document.getElementById('divNavigator');
     var divOuter=document.getElementById('divOuter');
     //设置divNavigator的left的值
     /*console.log(divOuter.offsetWidth);
       console.log(divNavigator.clientWidth);*/
     divNavigator.style.left=(divOuter.offsetWidth -divNavigator.offsetWidth)/2+'px';
     //获取所有的a标签
     var aArray=document.getElementsByTagName('a');
     //设置第一张默认为黑色
     aArray[0].style.backgroundColor='black';
     //点击超链接切换到指定的图片
     //1.点击第一个超链接,显示第一个图片...以此类推
     //2.为所有的超链接绑定单击响应函数
     var index=0;
     ulImageList.style.left=index*-572+'px';
     for(var i=0;i<aArray.length;i++){
         //为每一个超链接都添加一个onlyMark属性
         aArray[i].onlyMark=i;
         aArray[i].οnclick=function(){
             //关闭自动切换的定时器
             clearInterval(mySetInterval);
             //获取点击超链接的索引,并将其设置为index
             //alert(this.onlyMark);
             index=this.onlyMark;
             //切换图片
             //1.第一张 0 0 第二张 1 -572 第三张2 -572*2
             //ulImageList.style.left=index*-572+'px';
             setA(aArray,index);
             move(ulImageList,"left",index*-572,20,function(){
                 //动画执行完毕,再次开启自动切换
                 autoChange();
             });
         };
     }
     //自动切换图片
     autoChange();
     var mySetInterval;
     function autoChange(){
         //开启一个定时器,定时切换图片
         mySetInterval=setInterval(function(){
             //使索引自增
             index++;
             //判断index的值
             index=index%(imageArray.length);
             //console.log(index);
             //执行动画
             move(ulImageList,"left",index*-572,20,function(){
                 //修改导航按钮
                 setA(aArray,index);
             });
         },3000);
     }
     //创建一个方法用来设置选中的a
     function setA(myArray,myIndex){
         //判断当前索引是否为最后一张图片
         if(index>=imageArray.length-1){
             //则将index设置为0
             index=0;
             //此时显示的是最后一张图片,而最后一张与第一张是一样的
             //通过css将最后一张切换成第一张
             ulImageList.style.left=0+"px";
         }
         for(var i=0;i<myArray.length;i++){
             //myArray[i].style.backgroundColor='red';
             //让内联样式生效
             myArray[i].style.backgroundColor='';
         }
         myArray[index].style.backgroundColor='black';
     }
     function move(myObject,attr,target,speed,callback){
         //防止多次点击开启多个定时器的问题
         clearInterval(myObject.mySetInterval);
         //获取当前值
         var currentValue=parseInt(getStyle(myObject,attr));
         if(currentValue>target){
             //此时speed为负值
             speed=-speed;
         }
         //开启定时器,用来执行动画效果
         myObject.mySetInterval=setInterval(function(){
             //获取div1原理left值
             var oldValue=parseInt(getStyle(myObject,attr));
             //判断速度的正负值
 
             //在旧的基础上增加
             var newValue=oldValue+speed;
             //向左移动是否小于target
             //向右移动是否大于target
             if((speed<0&&newValue<target) || (speed>0&&newValue>target)){
                 newValue=target;
             }
             //新值设置给div1
             myObject.style[attr]=newValue+'px';
             //到达目标关闭定时器
             if(newValue==target){
                 clearInterval(myObject.mySetInterval);
                 //动画执行完毕,调用回调函数
                 if(callback){
                     callback();
                 }
             }
         },30);
     }
     function getStyle(obj,name){
         if(window.getComputedStyle){
             return getComputedStyle(obj,null)[name];
         }else{
             return obj.currentStyle[name];
         }
     }
 </script>
 
 </html>
 
(12)类的操作
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 <button id="myButton">点击按钮修改div的样式</button>
 <div id="myDiv" class="myDivClass"></div>
 </body>
 <style>
    .myDivClass{
        width: 100px;
        height: 500px;
        background-color: red;
    }
    .myDivClass2{
        width: 200px;
        background-color: yellowgreen;
    }
 </style>
 <script>
     //类的操作
     var myButton=document.getElementById('myButton');
     var myDiv=document.getElementById('myDiv');
     myButton.οnclick=function(){
         //修改div的样式
         //1.这样浏览器每次都需要渲染一次页面
         //2.执行性能差,而且修改多个样式也不太方便
         /*my_div.style.width='200px';
         my_div.style.height='200px';
         my_div.style.backgroundColor='yellow';*/
         //我希望一行代码,可以同时修改多个样式
         //修改box的class属性
         //1.所以我们可以通过元素的class属性来简介的修改样式
         //2.这样一来,我们只需要修改一次,即可同时修改多个样式
         //3.浏览器只需要重新渲染页面一次,性能比较好
         //4.并且这种方式可以使表现和行为进一步的分离
         //5.也实现了进一步将JS与CSS的分离
         //myDiv.className='myDivClass2';
         //6.实现两个class叠加的效果
         /*if(!hasClass(myDiv,'myDivClass2')){
             addClass(myDiv,'myDivClass2');
         }
         alert('3秒后即将删除myDivClass2');
         setTimeout(function(){
             deleteClass(myDiv,'myDivClass2');
         },3000);*/
         toggleClass(myDiv,'myDivClass2');
     }
     //定义一个函数,用来向一个元素中添加指定的class的值
     //1.obj 要添加class属性的元素
     //2.cn 要添加的class的值
     function addClass(obj,cn){
         obj.className+=" "+cn;
     }
     //判断元素中是否含有指定的属性值
     function hasClass(obj,cn){
         //var myReg=/cn/;
         var myRegExp=new RegExp(""+cn+"");
         return myRegExp.test(obj.className);
     }
     //删除一个元素中指定的class
     function deleteClass(obj,cn){
         //创建一个正则表达式
         var myRegExp=new RegExp(""+cn+"");
         obj.className=obj.className.replace(myRegExp,"");
     }
     //切换一个类
     //1.如果元素中具有该类,则删除
     //2.如果元素中没有该类,则添加
     function toggleClass(obj,cn){
         if(hasClass(obj,cn)){
             //有则删除
             deleteClass(obj,cn);
         }else{
             addClass(obj,cn);
         }
     }
 </script>
 </html>
 
(13)二级菜单
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 <div id="myDivMenu" class="myDivMenuClass">
     <div>
         <span class="mySpanMenuClass">在线工具</span>
         <a href="#">图像优化</a>
         <a href="#">收藏夹图标生成器</a>
         <a href="#">邮件</a>
         <a href="#">htaccess密码</a>
         <a href="#">梯度图像</a>
         <a href="#">按钮生成器</a>
     </div>
     <div class="myDivCollapsedClass">
         <span class="mySpanMenuClass">支持我们</span>
         <a href="#">推荐我们</a>
         <a href="#">连接我们</a>
         <a href="#">网络资源</a>
     </div>
     <div class="myDivCollapsedClass">
         <span class="mySpanMenuClass">合作伙伴</span>
         <a href="#">工具包</a>
         <a href="#">CSS驱动</a>
         <a href="#">CSS例子</a>
     </div>
 </div>
 
 </body>
 <style>
     *{
         margin: 0;
         pading: 0;
         list-style-type: none;
     }
     a,img{
         border: 0;
         text-decoration: none;
     }
     body{
         font: 12px/180% Arial,Helvetica,sans-serif,'新宋体';
     }
     .myDivCollapsedClass{
         height: 25px;
     }
     .myDivMenuClass{
         width: 150px;
         margin: 0 auto;
         font-family: Arial,sans-serif;
         font-size:12px;
         padding-bottom: 10px;
         background: #4d5669;
         color: #fff;
     }
     .myDivMenuClass div{
         background: #2b85e4;
         overflow: hidden;
     }
     .myDivMenuClass div span{
         display:block;
         height:15px;
         line-height: 15px;
         overflow: hidden;
         padding:5px 25px;
         font-weight: bold;
         color:white;
         background:grey 10px center;
         cursor:pointer;
         border-bottom:1px solid #add;
     }
 </style>
 <script>
     //二级菜单
     //1.每一个菜单都是一个div
     //2.当div具有myDivCollapsedClass这个类时,div就是折叠的
     //3.当div没有这个类就是展开的状态
     //点击菜单,切换菜单的显示状态
     //获取span
     var mySpanMenuArray=document.querySelectorAll(".mySpanMenuClass");
     console.log(mySpanMenuArray.length);
     //定义个变量,来保存当前打开的菜单
     var openDiv=mySpanMenuArray[0].parentNode;
     //为每个span绑定单击响应函数
     for(var i=0;i<mySpanMenuArray.length;i++){
         mySpanMenuArray[i].οnclick=function(){
             //this代表当前点击的span
             var parentDiv=this.parentNode;
             //来关闭parentDiv
             toggleClass(parentDiv,'myDivCollapsedClass');
             //打开关闭以后,应该关闭之前打开的菜单
             //判断openDiv和parentDiv是否相同
             if(openDiv!=parentDiv){
                 //为了统一处理动画的过渡效果,希望将addClass改为toggleClass
                 //addClass(openDiv,'myDivCollapsedClass');
                 //此处toggleClass不需要移出,只需要加上
                 if(!hasClass(openDiv,'myDivCollapsedClass')){
                     toggleClass(openDiv,'myDivCollapsedClass');
                 }
             }
             //修改openDiv为当前打开的菜单
             openDiv=parentDiv;
         };
     }
     function addClass(obj,cn){
         obj.className+=" "+cn;
     }
     //判断元素中是否含有指定的属性值
     function hasClass(obj,cn){
         //var myReg=/cn/;
         var myRegExp=new RegExp(""+cn+"");
         return myRegExp.test(obj.className);
     }
     //删除一个元素中指定的class
     function deleteClass(obj,cn){
         //创建一个正则表达式
         var myRegExp=new RegExp(""+cn+"");
         obj.className=obj.className.replace(myRegExp,"");
     }
     //切换一个类
     //1.如果元素中具有该类,则删除
     //2.如果元素中没有该类,则添加
     function toggleClass(obj,cn){
         if(hasClass(obj,cn)){
             //有则删除
             deleteClass(obj,cn);
         }else{
             addClass(obj,cn);
         }
     }
 </script>
 </html>
 
(14)二次菜单的过渡效果
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 <div id="myDivMenu" class="myDivMenuClass">
     <div>
         <span class="mySpanMenuClass">在线工具</span>
         <a href="#">图像优化</a>
         <a href="#">收藏夹图标生成器</a>
         <a href="#">邮件</a>
         <a href="#">htaccess密码</a>
         <a href="#">梯度图像</a>
         <a href="#">按钮生成器</a>
     </div>
     <div class="myDivCollapsedClass">
         <span class="mySpanMenuClass">支持我们</span>
         <a href="#">推荐我们</a>
         <a href="#">连接我们</a>
         <a href="#">网络资源</a>
     </div>
     <div class="myDivCollapsedClass">
         <span class="mySpanMenuClass">合作伙伴</span>
         <a href="#">工具包</a>
         <a href="#">CSS驱动</a>
         <a href="#">CSS例子</a>
     </div>
 </div>
 
 </body>
 <style>
     *{
         margin: 0;
         pading: 0;
         list-style-type: none;
     }
     a,img{
         border: 0;
         text-decoration: none;
         width: 120px;
         float: left;
     }
     body{
         font: 12px/180% Arial,Helvetica,sans-serif,'新宋体';
     }
     .myDivCollapsedClass{
         height: 25px;
     }
     .myDivMenuClass{
         width: 100px;
         margin: 0 auto;
         font-family: Arial,sans-serif;
         font-size:12px;
         padding-bottom: 10px;
         background: #4d5669;
         color: #fff;
     }
     .myDivMenuClass div{
         background: #2b85e4;
         overflow: hidden;
     }
     .myDivMenuClass div span{
         display:block;
         height:15px;
         line-height: 15px;
         overflow: hidden;
         padding:5px 25px;
         font-weight: bold;
         color:white;
         background:grey 10px center;
         cursor:pointer;
         border-bottom:1px solid #add;
     }
 </style>
 <script>
     //二级菜单
     //1.每一个菜单都是一个div
     //2.当div具有myDivCollapsedClass这个类时,div就是折叠的
     //3.当div没有这个类就是展开的状态
     //点击菜单,切换菜单的显示状态
     //获取span
     var mySpanMenuArray=document.querySelectorAll(".mySpanMenuClass");
     console.log(mySpanMenuArray.length);
     //定义个变量,来保存当前打开的菜单
     var openDiv=mySpanMenuArray[0].parentNode;
     //为每个span绑定单击响应函数
     for(var i=0;i<mySpanMenuArray.length;i++){
         mySpanMenuArray[i].οnclick=function(){
             //this代表当前点击的span
             var parentDiv=this.parentNode;
 
             //在切换类之前,获取元素的高度
             var begin=parentDiv.offsetHeight;
 
             //来关闭parentDiv
             toggleClass(parentDiv,'myDivCollapsedClass');
 
             //切换类之后获取一个高度
             var end=parentDiv.offsetHeight;
 
             //动画效果就是将高度从begin向end过渡
             //将元素的高度重置为begin
             parentDiv.style.height=begin+'px';
 
             //执行动画
             move(parentDiv,'height',end,10,function(){
                 //动画执行完毕,删除内联样式
                 parentDiv.style.height="";
             });
 
             //打开关闭以后,应该关闭之前打开的菜单
             //判断openDiv和parentDiv是否相同
             if(openDiv!=parentDiv){
                 //为了统一处理动画的过渡效果,希望将addClass改为toggleClass
                 //addClass(openDiv,'myDivCollapsedClass');
                 //此处toggleClass不需要移出,只需要加上
                 if(!hasClass(openDiv,'myDivCollapsedClass')){
                     //在切换类之前,获取元素的高度
                     var begin1=parentDiv.offsetHeight;
                     toggleClass(openDiv,'myDivCollapsedClass');
                     //切换类之后获取一个高度
                     var end1=parentDiv.offsetHeight;
                     //动画效果就是将高度从begin向end过渡
                     //将元素的高度重置为begin
                     parentDiv.style.height=begin1+'px';
                     //执行动画
                     move(parentDiv,'height',end1,10,function(){
                         //动画执行完毕,删除内联样式
                         parentDiv.style.height="";
                     });
                 }
             }
             //修改openDiv为当前打开的菜单
             openDiv=parentDiv;
         };
     }
     function addClass(obj,cn){
         obj.className+=" "+cn;
     }
     //判断元素中是否含有指定的属性值
     function hasClass(obj,cn){
         //var myReg=/cn/;
         var myRegExp=new RegExp(""+cn+"");
         return myRegExp.test(obj.className);
     }
     //删除一个元素中指定的class
     function deleteClass(obj,cn){
         //创建一个正则表达式
         var myRegExp=new RegExp(""+cn+"");
         obj.className=obj.className.replace(myRegExp,"");
     }
     //切换一个类
     //1.如果元素中具有该类,则删除
     //2.如果元素中没有该类,则添加
     function toggleClass(obj,cn){
         if(hasClass(obj,cn)){
             //有则删除
             deleteClass(obj,cn);
         }else{
             addClass(obj,cn);
         }
     }
     function move(myObject,attr,target,speed,callback){
         //防止多次点击开启多个定时器的问题
         clearInterval(myObject.mySetInterval);
         //获取当前值
         var currentValue=parseInt(getStyle(myObject,attr));
         if(currentValue>target){
             //此时speed为负值
             speed=-speed;
         }
         //开启定时器,用来执行动画效果
         myObject.mySetInterval=setInterval(function(){
             //获取div1原理left值
             var oldValue=parseInt(getStyle(myObject,attr));
             //判断速度的正负值
 
             //在旧的基础上增加
             var newValue=oldValue+speed;
             //向左移动是否小于target
             //向右移动是否大于target
             if((speed<0&&newValue<target) || (speed>0&&newValue>target)){
                 newValue=target;
             }
             //新值设置给div1
             myObject.style[attr]=newValue+'px';
             //到达目标关闭定时器
             if(newValue==target){
                 clearInterval(myObject.mySetInterval);
                 //动画执行完毕,调用回调函数
                 if(callback){
                     callback();
                 }
             }
         },30);
     }
     function getStyle(obj,name){
         if(window.getComputedStyle){
             return getComputedStyle(obj,null)[name];
         }else{
             return obj.currentStyle[name];
         }
     }
 </script>
 </html>
 
(15)JSON
<!DOCTYPE html>
 <html lang="cn" xmlns:th="http://www.thymeleaf.org" xmlns:v-bind="http://www.w3.org/1999/xhtml"
       xmlns:v-on="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="application/json; charset=UTF-8">
     <meta name="referrer" content="never">
     <title>JS</title>
 </head>
 <body>
 <!--创建一个外部的div,来作为大的容器-->
 
 </body>
 <style>
 
 </style>
 <script>
     //JSON
     //1.JS中的对象只有JS自己认识,其他语言都不认识
     //2.所以要把它转换为大家都认识的。
     //创建一个对象
     var myObject={"name":"陈翔","age":18,"sex":"男"};
     console.log(myObject);
     console.log(typeof myObject);
     var myJson='{"name":"陈翔","age":18,"sex":"男"}';
     console.log(myJson);
     console.log(typeof myJson);//打印出String
     //3.所以Json就是特殊格式的字符串,它可以被任何的语言识别
     //4.而且可以转换为任意语言中的对象
     //5.所以JSON在开发中主要用于数据的交互
     //6.JSON JavaScript Object Notation JS对象表示法
     //7.Json的格式和JS对象的格式一样,只不过JSON字符串中的属性必须加双引号
     //8.其他的和JS语法一致
     //9.Json分类  (1)对象{}   (2)数组[]
     //10.JSON中允许的值:字符串、数值、布尔值、null、对象、数组
 
     //11.Json转换为对象
     //12.JS中为我们提供了一个工具类,就叫JSON
     //这个对象可以帮助我们把JSON—>JS,也可以把JS—>JSON
     //13.因为JS直接myJson.属性取不到
     var tempObject=JSON.parse(myJson);
     console.log(tempObject.name);
     //14.JS对象转JSON
     var tempJson=JSON.stringify(myObject);
     console.log(tempJson);
     console.log(typeof tempJson);
     //15.JSON这个对象在IE7及以下对象不支持,所以在这些浏览器中会报错
     var IE7Json='{"name":"陈翔","age":18,"sex":"男"}';
     //16.eval()这个函数可以执行一段字符串形式的JS代码,
     //并将执行结果返回。
     //17.如果执行的eval中含有{},它会将{}当成是代码块,
     //如果不希望将其当成代码块,则需要再字符串前后各加一个()
     //var tempStr="alert('Hello')";
     //eval(tempStr);
     var IE7Object=eval("("+IE7Json+")");
     console.log(IE7Object);
     //18.eval()虽然很强大,但是开发者尽量不要使用
     //应为是执行性能差,而且存在安全隐患。
     //19.也可以通过引入外部的JS文件来处理。json2.js
 </script>
 </html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值