javascript基础&实战

javascript基础&实战

一、JS基础

1.js编写位置

​ 1.在head中添加

image-20221228102322887

  1. 在body中的语句上添加 不推荐使用

    image-20221228102453678

2.引入外部js文件

image-20221228102542233

3.js基本语法

image-20221228103613580

4.变量 赋值

image-20221228104332940

5.标识符

image-20221228105353246

6.数据类型

image-20221228112319990

1.String 字符串

image-20221228112403331

2. Number

image-20221228114832118

image-20221228114845034

3.布尔值

image-20221228115238137

4. Null 和 Undefined

image-20221228120057229

5.强制类型转换-String

image-20221228164012388

image-20221228164025226

6.强制类型转换-Number

<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			/* 
				将其他的类型转换为Number
				 转换方式一:
					使用Number()函数
							- 字符串 -->  数字
							  1.如果是纯数字的字符串,则直接将其转换为数字
							  2. 如果字符串中有非数字的内容,则转换为NaN
							  3.如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
													
							- 布尔 --> 数字
							   true 转成 1
							   false 转成 0
							   
							- null --> 数字  0
							- undefined -->数字  NaN   
							
				 转换方式二:
						 - 这种方式专门用来对付字符串
						 - parseInt() 把一个字符串转换为一个整数
						 - parseFloat() 把一个字符串转换为一个浮点数
			 */
			
			var a = "123";
			a = Number(a);
			
			var b = "  "
			b = Number(b);  //转换为 0
			
			b =true;
			b=Number(b); //转换为 1
			
			b= null;
			b=Number(b);  //转换为 0
			
			console.log(typeof a);
			console.log(a);
			console.log(typeof b);
			console.log(b);
			
		   var d= "6a123px1aa2";  // 输出 6
		   //调用parseInt()函数将a转换为Number
		   /* 
				parseInt()可以将一个字符串中的有效的整数内容取出来
					然后转换为 Number
		   */
		   d=parseInt(d);
		   
		   d= "123.432aa";  //输出 123.432
		   // parseFloat() 作用和parseInt()类似,不同的是它可以获得有效的小数
		   d=parseFloat(d);
		   console.log(typeof d);
		   console.log(d); 
			
		</script>
	</head>

7.其他进制的数字

<script type="text/javascript">
			/* 
				在js中,如果需要表示16进制的数字,则需要以0x开头
						如果需要表示8进制的数字,则需要以0开头
						如果需要表示2进制的数字,则需要以0b开头  不是所有浏览器都支持
			 */
			// 十六进制
			a=0x20; //32
			a = 0xff; //255
			a = 0xcafe; //51966
			
			// 八进制
			a= 070; //56
			
			//二进制
			a = 0b10;  //2
			
			//向“070”这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析
			a="070"
			//可以在parseInt()中传递一个第二个参数,来制定数字的进制
			a= parseInt(a,10); //70
			//a= parseInt(a,8); //56
			
			console.log(a);
			
		</script>

8.转化为 Boolean

	<script type="text/javascript">
			/* 
				将其他的数据类型转换为Boolean
					-使用Boolean()函数
						- 数字 ---> 布尔
						  - 除了0和NaN,其余的都是true
						- 字符串 ---> 布尔
						   - 除了空串,其余的都是true
						- null和 undefined 都会转换为false   
						- 对象也会转换为 true
			 */
			
			var a= 123; // true
				a=-123;// true
				a=0; // false
				a = Infinity; // true
				a= null;  //false
				a = undefined; //flase
				a=NaN; //false
				
				a= ""; //false
				a= " ";  //true
				a= Boolean(a);
				
				console.log(typeof a);
				console.log(a);
			
		</script>

9.算数运算符

<script type="text/javascript">
			/* 
				运算符也叫操作符
					通过运算符可以对一个或多个值进行运算,并获取运算结果
					比如: typeof 就是运算符,可以来获得一个值的类型
					     它会将该值的类型以字符串的形式返回
							number string boolean undefined object
							
				算数运算符
					对将非Number类型的值进行运算时,会将这些值转换为Number然后在运算
						任何值和NaN做运算都得 NaN
					+
					  +可以对两个值进行加法运算,并将结果返回
					  如果对两个字符串进行加法运算,则会做拼串  会将两个字符串拼接为一个字符串,并返回
					   任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串的操作	
					-
					   -可以对两个值进行减法运算,并将结果返回	
					*
					   * 可以对两个值进行乘法运算
					/	
					   / 可以对两个值进行除法运算	
					% 
						% 取模运算
			 */
			
			
			var a= 123;
			var result = typeof a;  //string
			console.log(typeof result);
			result= a+1;  // 124
			result = 123+1234; //1357
			result = true + false; //1
			result = true + 1;  //2
			result = null + 1; //
			result = NaN + 1; //NaN
			
			result = "123"+"453";  //123453   字符串拼接
			result = "你好"+"陌生人";  //你好陌生人
			
			result = 123+"1";  // 1231
			result = true + "hello";  //truehello
			result = true + "1"; //true1
			console.log(result);
			 
			 /* 
				任何值和字符串相加都会转换为字符串,并做拼串操作
				  我们可以利用这一特点,来将一个任意的数据类型转换为String
				   我们只需要为任意的数据类型 + 一个 ""  即可将其转换为String
				   这是一种隐式的类型转换,由浏览器自动完成,实际上它也是调用String()函数
			 */
			 var c = 123;
			 c = c + ""; // 类型为  string
			 
			 console.log(typeof c);
			  console.log("c = " + c);  //c = 123
			  
			  result = 1 + 2 + "3";  //33
			  result = "1" + 2 + 3; //123
			  console.log(result);
			 
			 //减法
			 result = 100 - 5; //95
			 result = 100 - true; // 99
			 result = 100 - "1"; //99
			 console.log(result);
			 	
			//乘法
			  result = 2 * 2; //4
			  result = 2 * "8"; //16
			  result = 2 * undefined;  //NaN
			  result = 2 * null; //0
			  	  
			 console.log(result);		 
			//除法	
			 result = 4 / 2; //2
			 result = 3 / 2; //1.5
			 console.log(result);
			 /* 
				任何值做 - * / 运算时都会自动转换为Number
				 我们可以利用这一特点做隐式的类型转换
					可以通过和一个值 -0 *1 /1 来将其转换为Number
					 原理和Number()函数一样,使用起来更加简单
			 */
			 var d= "123";
			 d=d-0; //123
			 console.log(typeof d); //number
			console.log(d);
			 
			 //% 取模
			 result =  9 % 3; //0
			 result = 9 % 4; //1
			 console.log(result);
			 
		</script>

10.一元运算符

	<script type="text/javascript">
			/* 
				一元运算符, 只需要一个操作数
					+ 正号
						- 正号不会对数字产生任何影响
					- 负号
						- 负号可以对数字进行负号的取反
						
				  - 对于非Number 类型的值,
						它会先转换为Number,然后在运算
						可以对一个其他的数据类型使用+,来将其转换为number
						 它的原理和Number()函数一样
			 */
			
			var a= 123;
			a = +a; //123
			a = -a; //-123
			
			a = true;
			//a = -a; //-1
			//a = +a; // 1
			
			a= "18"
			a = +a; //18
			console.log(a);
			
			a = 1 + "2" + 3; //123
			a = 1 + +"2" + 3;  //6   +"2"会将其转化为数字2
			console.log(a);
			
			
		</script>

11.自增和自减

<script type="text/javascript">
			/* 
				自增   ++
				  - 通过自增可以使变量在自身的基础上增加1
				  - 对于一个变量自增以后,原变量的值会立即自增1	  
				  - 自增分成两种: 后++(a++)  和 前++(++a)  ,但都会立即使原变量的值自增1
				  a++的值等于原变量的值(自增前的值)
				  ++a的值等于原变量新值 (自增后的值)
				  
			    自减   --
				  - 通过自减可以使变量在自身的基础上减1
				  -自减分成两种: 后--(a--) 和前--(--a)	但都会立即使原变量的值自减1		  
				  a--的值等于原变量的值(自减前的值)
				  --a的值等于原变量新值 (自减后的值)
			*/
			var a = 1;
			a++;
			console.log(a);
			
			var d= 20;
			// 20 + 22 + 22
			var result = d++ + ++d + d;
			console.log("result= " +  result); //result= 64

			d = 10;
			console.log(d--); //10
			
		</script>

12.逻辑运算符 (! && ||)

<script type="text/javascript">
			/* 
				JS中为我们提供了三种逻辑运算符
				! 非
				  - !可以用来对一个值进行非运算	
				  - 所谓非运算就是值对一个布尔值进行取反操作,
						   true 变false  ,false 变true
				  - 如果对一个值进行两次取反,它不会变化
				  - 如果对非布尔值进行取反,则会将其转换为布尔值,然后再取反
						所以我们可以利用该特点,来将一个其他的数据类型转换为布尔值
						可以为一个任意数据类型去两次反,来将其转换为布尔值,
						 原理和Boolean()函数一样
						   
				&& 与
				  - &&可以对符号两侧的值进行与运算并返回结果
				  - 运算规则
						- 两个值中只要有一个值为false就返回false
						    只有两个值都为true时,才会返回true
						- JS中的"与"属于短路的与,
							如果第一个值为false,则不会看第二个值
						
				|| 或
				  - ||可以对符号两侧的值进行或运算并返回结果
				  - 运算规则:
						- 两个值中只要有一个 true,就返回true
							 如果两个值都为false,才返回false
						- JS中的"或"属于短路的或	
						   如果第一个值为true,则不会检查第二个, 只有第一个为false,才会检查第二个
			 */
			
			var a = true;
			
			a= !a; //false
			console.log(a);
			
			a = "hello"
			a = !!a;  //true
			console.log(a);
			
			// 两个值都是true,则返回true
			var result  = true && true;  //result = true
			//只有有一个false ,就返回false
			var result  = true && false;  //result = false
			var result  = false && true; 
			var result  = false && false; 
			console.log("result = " + result); 
			
			//第一个值为false,不会检查第二个值
			false && alert("看我出不出来");
			
			// 两个都是false,则返回false
			result =  false || false; //fasle
			//只要有一个true,就返回true
			result =  true || false; //true
			result =  false || true; 
			result =  true || true;
			console.log(result);
			//第一个值为false, 则会检查第二个值
			false || alert("123");
			//第一个值为true, 则不再检查第二个值
			true || alert("123");
			
		</script>

13. 非布尔值的与或运算

<script type="text/javascript">
			/* 
				&& || 非布尔值的情况
				  - 对于非布尔值进行与或运算时,
				     会将其转换为布尔值,然后再运算,并且返回原值
				 - 与运算:
					- 如果第一个值为true,则必返回第二个值
					- 如果第一个值为false,则直接返回第一个值
					
				 - 或运算
					 -如果第一个值为true,则直接返回第一个值
					 -如果第一个值为false,则直接返回第二个值
			 */
			
			// 与运算:  如果两个值都为true,则返回后边的
			var result = 1 && 2; //返回 2
			
			//与运算: 如果两个值中有false,则返回靠前的false
			result = 0 && 2;  // 0
			result = 2 && 0; //0
			result = NaN && 0; //NaN
			result = 0 && NaN; //0
			console.log(result);
			
			//如果第一个值为true,则直接返回第一个值
			result = 2||1; // 2
			result = 2||0; // 2
			
			//如果第一个值为false,则直接返回第二个值
			result = NaN || 1; //1
			result = NaN || 0; //0
			
			result = "" || "hello"; //hello
			result = -1 || "你好";
			console.log(result);
			
			
			
		</script>

14.赋值运算符

<script type="text/javascript">
			/* 
				=
				  可以将符号右侧的值赋值给符号左侧的变量
				  
				+=  -=  *= /=  %=
			 */
			var a = 123;
			
			//a += 5;  //128
			
			a -= 5; //118
			
			console.log(a);
			
		</script>

15.关系运算符

<script type="text/javascript">
			/* 
				通过关系运算符可以比较两个值之间的大小关系,
				如果关系成立它会返回true,如果关系不成立则返回false
				
				> 大于号
				  - 判断符号左侧的值是否大于右侧的
				  - 如果关系成立,返回true,如果关系不成立则返回false
				
				>= 大于等于
				  - 判断符号左侧的值是否大于或等于右侧的值
				  
				< 小于号
				<= 小于等于
				  
				非数值的情况
					- 对于非数值进行比较时,会将其转换为数字然后在比较
					- 如果符号两侧的值都是字符串时,不会将其转换为数字进行比较,
					而会分别比较字符串中的字符的Unicode编码
			 */
			
			console.log(5 > 8); //fasle
			console.log(5>=5); // true
			
			console.log(1 > true); //false
			console.log(1 >= true); //true
			console.log(1 > "0");  //true
			console.log(1 > null);  //true
			//任何值和NaN做任何比较都是false
			console.log(10 > "hello");  //fasle
			
			console.log(true > false); //true
			console.log("1" < "5"); //true
			console.log("11" < "5"); //true
			
			console.log("a" < "b"); //true
			//比较字符编码时是一位一位进行比较
			console.log("asd" < "a"); //false
			
			//如果比较的两个字符串型的数字,可能会得到不可预期的结果
			// 注意: 在比较两个字符串类型的数字时,一定一定一定要转型
			console.log("11123" < +"5"); //false
			console.log("11123" < "5"); //true
		</script>

16.相等运算符

	<script type="text/javascript">
			/* 
				相等运算符用来比较两个值是否相等,
				  如果相等会返回true, 否则返回false
				  
				  使用 == 来做相等运算
					- 当使用==来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型
					然后再比较
					
				 不相等
					不相等用来判断两个值是否不相等,如果不相等返回true,否则返回false
					- 使用 != 来做不相等运算
					- 不相等也会对变量进行自动的类型转换,如果转换后相等它也返回false
					
				=== 
					全等
					- 用来判断两个值是否全等,它和相等类似,不同的是他不会做自动的类型转换
					   如果两个值的类型不同,直接返回false
				!==
					不全等
					- 用来判断两个值是否不全等,和不等类似,不同的是它不会做自动类型转换
					   如果两个值的类型不同,直接返回true
					   
			 */
			
			var a= 10;
			console.log(a == 4); //false
			
			console.log("1" == 1); //true
			
			console.log(true == "1"); //true
			
			console.log(null == 0);  //false
			
			/* 
				undefined 衍生自null
				 所以这两个值做相等判断时,会返回true
			 */
			console.log(undefined  == null); //true
			
			//NaN 不和任何值相等,包括它本身
			console.log(NaN == NaN); //false
			
			
			//可以通过isNaN()函数来判断一个值是否是NaN
				// 如果该值是NaN则返回true,否则返回false
			var b = NaN;
			console.log(isNaN(b)); //true
			
			console.log(10 != 5); //true
			console.log("abcd" != "abcd"); //false
			
			console.log("123" === 123); //false
			console.log(null === undefined); //false
			
			console.log("12" !== 12); //true
			
		</script>

17.条件运算符

		<script type="text/javascript">
			/* 
				条件运算符也叫三元运算符
				  语法:
					  条件表达式 ? 语句1 : 语句2;
					  
				 如果条件的表达式的求值结果是一个非布尔值,
					   会将其转换为布尔值然后在运算
			 */
			
			var a=10,b=20,c=50;
			// a>b?alert("a大"):alert("b大");
			//获取a和b中的最大值
			var max = a>b?a:b; //20
			//获取a b c中的最大值
			max = max > c ? max :c; //50
			console.log(max);
			
			"hello"?alert("1"):alert("2"); // 1
			""?alert("1"):alert("2"); // 2
			
		</script>

18.运算符的优先级

<script type="text/javascript">
			/* 
				就和数学中一样,在JS中运算符也有优先级
				   比如: 先乘除,后加减
				在JS中有一个运算符优先级的表,
				    在表中越靠上优先级越高,优先级越高越优先计算,
					如果优先级一样,则从左往右计算。
			 */
			
			var a= 1|| 2 && 3; //1
			var a= (1|| 2) && 3;  //3
			console.log(a);
			
		</script>

image-20221229103900519

19.代码块

<script type="text/javascript">
			/* 
			    我们的程序是由一条一条语句构成的
				  语句是按照自下向上的顺序一条一条 执行的
				  在JS中可以使用{}来为语句进行分组,
					同一个{}中的语句我们称为是一组语句,
					它们要么都执行,要么都不执行
					一个{}中的语句我们也称为一个代码块
					在代码快的后边就不用再编写;了
					
				 JS中的代码块,只具有分组的作用,没有其他的用途	
			 */
			{
				var a = 10;
				alert("hello");
				console.log("你好");
				document.write("语句");
			}
			console.log("a= " +a);
			
		</script>

20. if语句

	<script type="text/javascript">
			/* 
				流程控制语句
					- JS中的程序是从上到下一行一行执行的
					- 通过流程控制语句可以控制流程执行流程
					   使程序可以根据一定的条件来选择执行
					- 语句的分类:
					   1.条件判断语句
					   2.条件分支语句
					   3.循环语句
					   
				条件判断语句:
					 - 使用条件判断语句可以在执行某个语句之前进行判断,
					   如果条件成立才会执行语句,条件不成立则语句不执行。
					 - if语句
					 -  语法一:
					    if(条件表达式)
						{
							语句1 ……	
						}
						
					- 语法二:		  
						if(条件表达式){
							 语句……
						}else{
							语句……
						}
						
					- 语法三:
						if(条件表达式){
							 语句……
						}else if(条件表达式){
							语句……
						}else{
							语句……
						}
			 */
			var a = 20;
			if(a > 10)
				alert("a比10大 ~~~");
				
			var b = 15;
			 if(a > 10 && a <= 20){
				 alert("a大于10,并且a小于等于20");
			 }
			 
			 var age = 50;
			 if(age >= 60){
				 alert("你己经退休了!!");
			 }else{
				 alert("你还没退休……");
			 }
			 
			 if(age > 100){
			 		alert("活着挺没意思的!!");
			 }else if(age > 60){
			 		 alert("退休了……");
			 }else if(age > 40){
				 alert("你已经年过半载了");
			 }else{
				 alert("你还是个小孩");
			 }
			
		</script>

练习

image-20221229114357068

image-20221229114422407

image-20221229114438181

练习2:
<script type="text/javascript">
			/* 	
				编写程序,由键盘输入三个数分别存入变量num1,num2,num3,
				对他们进行排序,并且从小到大输出
			 */
			
			// prompt()函数的返回值是String类型的
			var num1,num2,num3;
			num1 = +prompt("请输入整数num1:");  //通过加个+ 让其转换为number类型
			num2 = +prompt("请输入整数num2:");
			num3 = +prompt("请输入整数num3:");
			if(num1 < num2 && num1 < num3){
				//num1最小
				if(num2 < num3){
					alert(num1+","+num2+","+num3);
				}else{
					alert(num1+","+num3+","+num2);
				}
			}else if(num2 < num3 && num2 < num1){
				//num2最小
				if(num1 < num3){
					alert(num2+","+num1+","+num3);
				}else{
					alert(num2+","+num3+","+num1);
				}
			}else{
				//num3最小
				if(num2 < num1){
					alert(num3+","+num2+","+num1);
				}else{
					alert(num3+","+num1+","+num2);
				}
			}
			
			//alert(num1);
			
		</script>

21.条件分支语句--switch

<script type="text/javascript">
			/* 
				条件分支语句也叫switch语句
				语法:
				   switch(条件表达式){
					   case 表达式:
					        语句……
							break;
					   case 表达式:
					        语句……
					   		break;	
					   default:
							语句……
							break;	   
				   }
			 */
			
			var num = 2;
			switch(num){
				case 1: alert("壹"); break;
				case 2: alert("贰"); break;
				default: alert("0"); break;
			}
			
		</script>

22.while循环

<script type="text/javascript">
			/* 
				循环语句:
				  通过循环语句可以反复的执行一段代码多次
				  
				while循环
				  - 语法:
				    while(条件表达式){
						语句……
					}
				
				do ...  while循环
				 - 语法:
				    do{
						语句……
					}while(条件表达式);
				  
			 */
			
			var n = 1;
			/* while(n < 5){
				document.write(n++ + "<br/>");
				//alert(n++);
			} */
			
			do{
				document.write(++n + "<br/>");
			}while(n<5);
			
			
		</script>

23.for循环

<script type="text/javascript">
			/* 
				for语句,也是一个循环语句,也称为for循环
				 for循环的语法:
				 for(①初始化表达式;②条件表达式;④更新表达式){
					 ③语句……
				 }
				   for循环的执行流程:
				     ①执行初始化表达式,初始化变量 (初始化表达式只会执行一次)
					 ②执行条件表达式,判断是否执行循环。
							如果为true,则执行循环③
							如果为false,终止循环
					 ④执行更新表达式,执行更新表达式执行完毕继续重复②		
				 
			 */
			for(var i=0;i<10;i++){
				document.write(i);
			}
			
			//打印1-100之间所有奇数之和
			var sum = 0;
			for (var i= 1;i<=100;i+=2){
				sum += i;
			}
			document.write("<br/>奇数之和为: " + sum); //2500
			document.write("<br/>");
			//水仙花是指(1^3 + 5^3 + 3^3 = 153),打印所有的水仙花数
			
			for(var i=100;i<1000;i++){
				//获取i的百位 十位 个位的数字
				var bai = parseInt(i/100); //取整
				var shi = parseInt(i/10%10); //也需要取整
				var ge = i%10;
				if(bai*bai*bai + shi*shi*shi + ge*ge*ge == i){
					document.write("水仙花:" + i + "<br/>" );
				}
				// document.write(shi+" " );
			}
			
		</script>

练习

	<script type="text/javascript">
		
			for(var i=0;i<5;i++){
				for(var j=0;j<5;j++){
					 document.write("*&nbsp");
				}
				     document.write("<br/>");
			}
			/* 
			* * * * * 
			* * * * * 
			* * * * * 
			* * * * * 
			* * * * * */
			
			for(var i=1;i<=5;i++){
				for(var j=0;j<i;j++){
					 document.write("*&nbsp");
				}
				     document.write("<br/>");
			}
		/* 	* 
			* * 
			* * * 
			* * * * 
			* * * * *   */
			
			for(var i=5;i>=1;i--){
				for(var j=0;j<i;j++){
					 document.write("*&nbsp");
				}
				     document.write("<br/>");
			}
		/*  * * * * * 
			* * * * 
			* * * 
			* * 
			*    */

			//打印99乘法表			
			for(var i=1;i<=9;i++){
				for(var j=1;j<=i;j++){
					document.write(j+"*"+i +"="+ i*j+"&nbsp;&nbsp;");
				}
				document.write("<br/>");
			}
			
		</script>

23.1测试程序性能

<script type="text/javascript">
			
			//测试如下的程序的性能
			//在程序执行前,开启计时器
			//console.time("计时器的名字")可以用来开启一个计时器
			//它需要一个字符串作为参数,这个字符串将会作为计时器的标识
			console.time("test");
			
			for(var i=0;i<100;i++)
			 for(var j=0;j<i;j++)
				 {
					 console.log(j);
				 }
			
			//终止计时器
			//console.timeEnd()用来终止一个计时器,需要一个计时器的名字作为参数
			console.timeEnd("test");
			

			//可以通过 Math.sqrt()对一个数进行开方
			var rest = Math.sqrt(16);
			console.log(rest);

		</script>

24.break和continue

<script type="text/javascript">
			/* 
				break关键字可以用来退出switch或循环语句
				  不能在if语句中使用break和continue
				  break关键字,会立即终止离他最近的那个循环语句
			*/
		   
		   /* 
				可以为循环语句创建一个label,来标识当前的循环
				label:循环语句
				 使用break语句时,可以在break后跟着一个label,
				 这样break将会结束指定的循环,而不是最近的
		   */
		   
		  /* outer:
		   for(var i=0;i<5;i++){
			   console.log("@外出循环"+i);
			   for(var j=0;j<5;j++){
				   break outer;  //这样可以结束外层的for循环
				   console.log("内层循环"+j);
			   }
		   } */
			
			
			/* 
				continue关键字可以用来跳过当次循环
				  同样continue也是默认只会对离他最近的循环起作用
			 */
			for(var i=0;i<5;i++){				
				if(i==2){
						continue;  						
					}
				console.log("内层循环"+i);
			}
			
		</script>

25.对象的简介 -Object

<script type="text/javascript">
			/* 
				对象的分类:
				 1.内建对象
				     - 由ES标准中定义的对象,在任何的ES的实现中都可以使用
					 - 比如: Math String Number Boolean  Function Object
					 
				 2. 宿主对象
					  - 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
					  - 比如 BOM DOM
				 3. 自定义对象
					  - 由开发人员自己创建的对象
			 */
			
			//创建对象
			/* 
				使用new关键字调用的函数,是构造函数constructor
				  构造函数是专门用来创建对象的函数
				使用typeof检查一个对象时,会返回object  
			*/
			
			var obj = new Object();
			//console.log(typeof obj);  //object
			
			/* 
				在对象中保存的值称为属性
				向对象添加属性
				  语法: 对象.属性名 = 属性值;
			 */
			//向obj中添加一个name属性
			obj.name= "孙悟空";
			//向obj中添加一个gender属性
			obj.gender = "男";
			obj.age = 18;
			console.log(obj);  //{name: '孙悟空', gender: '男', age: 18}
			
			/**
			 *  读取对象中的属性
			 *   	语法: 对象.属性名
			 * 
			 *  如果读取对象中没有的属性,不会报错而是会返回undefined
			 */
			console.log(obj.name); //孙悟空
			
			/* 
				修改对象的属性值
				  语法: 对象.属性名= 新值
			 */
			obj.name="tom";
			console.log(obj.name);  //tom
			
			/* 
				删除对象的属性
					语法: delete 对象.属性名
			 */
			delete obj.name;
			console.log(obj.name); //undefined
			
		</script>

26.属性名和属性值

	<script type="text/javascript">
		
			var obj = new Object();
			/* 
				向对象中添加属性
				 属性名:
					- 对象的属性名不强制要求遵守标识符的规范
							但是我们使用时还是尽量按照标识符的规范去做
			 */
			obj.name = "孙悟空";
			obj.var = "hellow";
			console.log(obj.var); //hellow
			
			/* 
				如果要使用特殊的属性名,不能采用.的方式来操作
				需要使用另一种方式:
						语法: 对象["属性名"] = 属性值
				读取时也需要采用这种方式		
				
				使用[]这种形式去操作属性,更加灵活
				 在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
				
			 */
			obj["123"] = 432;
			obj["nihao"] = "你好";			
			var n = "nihao";
			
			console.log(obj["123"]); //432
			console.log(obj[n]);  //你好
			
			
			/* 
				属性值
					JS对象的属性值,可以是任意的数据类型
						  甚至也可以是一个对象
			*/
			obj.test = true;
			obj.test = null;
			
			//创建一个对象
			var obj2 = new Object();
			obj2.name = "猪八戒";
			
			//将obj2设置为obj的属性
			obj.test = obj2;
			console.log(obj.test); //{name: '猪八戒'}
			console.log(obj.test.name); //猪八戒
			
			
			/* 
				in 运算符
				  - 通过该运算符可以检查一个对象中是否含有指定的属性
				      如果有则返回true,没有则返回false
				  - 语法:
					  “属性名” in 对象	
			 */
			
			//检查obj中是否含有test2 属性
			console.log("test2" in obj); //false
			console.log("test" in obj); //true
			console.log("name" in obj); //true
			
			
		</script>

27.基本数据类型和引用数据类型

	<script type="text/javascript">
			/* 
				JS中的变量都是保存到栈内存中的,
					基本数据类型的值直接在栈内存中存储,
					值与值之间是独立存在,修改一个变量不会影响其他的变量
					
					对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,
					而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,
					当一个通过另一个变量修改属性时,另一个也会受到影响。
			 */
			
			var a= 123;
			b = a;
			a++;
			console.log(a); //124 
			console.log(b);  //123
			
			var obj3 = new Object();
			var obj4 = new Object();
			obj3.name="孙悟空";
			obj4.name="孙悟空";
			/* 
				当比较两个基本数据类型的值时,就是比较值
				而比较两个引用数据类型时,它是比较的对象的内存地址, 
					如果两个对象是一模一样的,但是地址不同,他也会返回false
			 */			
			console.log(obj3 == obj4);  //false
			
		</script>

image-20221229202407671

image-20221229202449746

image-20221229202422389

28.对象字面量

<script type="text/javascript">
			
			//创建一个对象
			var obj = new Object();
			
			/* 
				使用对象字面量来创建一个对象
			 */
			var obj2 = { };
			obj2.name = "孙悟空";
			console.log(obj2.name);  //孙悟空
			
			/* 
				使用对象字面量,可以在创建对象时,直接指定对象中的属性
				语法:{属性名:属性值,属性名:属性值……}
					对象字面量的属性名可以加引号也可以不加,建议不加,
					如果要使用一些特殊的名字,则必须加引号
					
				属性名和属性值是一组一组的名值对结构
				  名和值之间使用:连接,多个名值对之间使用,隔开
				  如果一个属性之后没有其他的属性了,就不要写,
			 */
			var obj3 = {
				name : "猪八戒",
				age : 18,
				gender : "性别",
				test:{
					name:"沙和尚",
					age:22
				}
			};
			console.log(obj3); //{name: '猪八戒', age: 18, gender: '性别'}
			console.log(obj3.test); //{name: '沙和尚', age: 22}
			console.log(obj3.test.name); //沙和尚
		</script>

29.函数的简介

<script type="text/javascript">
			/* 
				函数 function
				  - 函数也是一个对象
				  - 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
				  - 函数中可以保存一些代码在需要的时候调用
				  - 使用typeof检查一个函数对象时,会返回function		  
			 */
			//方法一
			//我们在实际开发中很少使用构造函数来创建一个函数对象
			//创建一个函数对象
			//可以将要封装的代码以字符串的形式传递给构造函数
			//var fun = new Function();
			    //var fun = new Function("console.log('hello 这是我的第一个函数');");
			//console.log(fun);
			
			//封装到函数中的代码不会立即执行
			//函数中的代码会在函数调用的时候执行
			//调用函数  语法: 函数对象()
			//当调用函数时,函数中封装的代码会按照顺序执行
			//fun();
			
			//方法二
			/* 
				使用 函数声明 来创建一个函数
				语法:
					 function 函数名([形参1,形参2..形参N]){
						 语句...
					 }
			 */
			function fun2(){
				console.log("这是我的第二个函数!!");
				document.write("~~┭┮﹏┭┮~~");
			}
			//调用fun2
			fun2();
			
			//方法三
			/* 
				使用 函数表达式来创建一个函数
				var 函数名 = function([形参1,形参2..形参N]){
						 语句...
					 }
			 */
			var fun3 = function(){
				console.log("我是匿名函数中封装的代码");
			};
			fun3();
			
		</script>

1.函数的参数

	<script type="text/javascript">
			/*
				定义一个用来求两个数和的函数
				 可以在函数的()中来指定一个或多个形参(形式参数)
				 多个形参之间使用,隔开,声明形参就相当于在函数内部声明了对应的变量,但是并不赋值
			  */
			 function sum( a, b){
				 console.log(a+b);
			 }
			 //在调用函数时,可以在()中指定实参(实际参数)
			 //实参将会赋值给函数中对应的形参
			sum(2,3);
			
			/* 
				调用函数时解析器不会检查实参的类型,
				 所以要注意,是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型检查
				函数的实参可以是任意的数据类型 
			 */
			sum(123,"hello"); //123hello
			sum(true,false); //1
			
			/* 
				调用函数时,解析器也不会检查实参的数量
				  多余实参不会被赋值
				  
				如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined  
			 */
			sum(123,432,"asda",true,null);  //555
			sum(123); //NaN
			
		</script>

2.函数的返回值

	<script type="text/javascript">
			
			/* 
				创建一个函数,用来计算三个数的和
				
				可以使用return 来设置函数的返回值
				语法:
					  return 值
				return后的值将会作为函数的执行结果返回,
					    可以定义一个变量,来接收结果
						
				在函数中return后的语句都不会执行		
				
				如果return语句后不跟任何值就相当于返回一个undefined,
				如果函数中不写return,则也会返回undefined
				
				return后可以跟任意类型的值
			 */
			
			function sum(a,b,c){
				var d = a+b+c;
				return d;
				//alert("hello") ;  //在此将不会被执行
				//return ; //相当于返回 undefined
				//return "hello";
			}
			//函数返回什么,result的值就是什么
			var result = sum(3,2,1);
			console.log(result); //6
			
		</script>

练习

<script type="text/javascript">
		
		//创建一个函数,可以在控制台输出一个人的信息
			var obj ={
				name:"孙悟空",
				age:18,
				gender:"男",
				address:"花果山"
			};
			function sayhello(o){
				console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+",家住在"+o.address);
			}
			
			sayhello(obj); //我是孙悟空,今年我18岁了,我是一个男,家住在花果山
			
			
			function fun(a){
				console.log("a = "+a);
			}
			fun(function(){alert("hello")}); //a = function(){alert("hello")}
			fun(sayhello);
			fun(sayhello(obj));
			
			/* 
				sayhello()
				   - 调用函数
				   - 相当于使用函数的返回值
				   
				 sayhello
				   - 函数对象
				   - 相当于直接使用函数对象
			 */
			
			
		</script>

3.立即执行函数

	<script type="text/javascript">
			
			//函数对象()
			/* 
				立即执行函数
				  函数定义完,立即被调用,这种函数叫做立即执行函数
				   立即执行函数往往只会执行一次
			 */
			(function(){
				alert("我是一个匿名函数");
			})();
			
			(function(a,b){
				console.log("a=" +a);
				console.log("b=" +b);
			})(123,434);   //a=123   b=434
			
		</script>

4. 函数的方法 call和apply

	<script type="text/javascript">
			/* 
				call()和apply()
				  - 这两个方法都是函数对象的方法,需要通过函数对象来调用
				  - 当对函数调用call()和apply()都会调用函数执行
				  - 在调用call()和apply()可以将一个对象指定为第一个参数
						此时这个对象将会成为函数执行时的this
				   - call()方法可以将实参在对象之后一次传递
				   - apply()方法需要将实参封装到一个数组中统一传递
							  
				 - this的情况:
					 1.以函数形式调用时,this永远都是window
					 2.以方法的形式调用时,this是调用方法的对象
					 3.以构造函数的形式调用时,this是新创建的那个对象
					 4.使用call和apply调用时,this是指定的那个对象
			 */
			function fun(a,b){
				console.log("a=" +a);
				console.log("b=" +b);
				//alert(this);
			}
			var obj ;
			fun.call(obj,2,3);

5.arguments

<script type="text/javascript">
			/* 
				在调用函数时,浏览器每次都会传递进两个隐含的参数,
					1.函数的上下文对象this
					2.封装实参的对象 arguments
					     - arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
						 - 在调用函数时,我们所传递的实参都会在arguments中保存
						 - arguments.length可以用来获取实参的长度
						 - 我们即使不定义形参,也可以通过arguments来使用实参,
								只不过比较麻烦
								arguments[0]  表示第一个实参
								arguments[1]  表示第二个实参
								
						 - 它里边有一个属性叫做callee
							   这个属性对应一个函数对象,就是当前正在执行的函数的对象
			 */
			
			function fun(){
				console.log(arguments instanceof Array); //false
				console.log(Array.isArray(arguments)); //false
				console.log(arguments.length); // arguments用来检查传递的实参的个数
				console.log(arguments[0]); //hello
				console.log(arguments.callee);
			}
			//fun();
			fun("hello",1,true); 
		</script>

30.枚举对象中的属性

		<script type="text/javascript">
			var obj = {
				name:"孙悟空",
				age:18,
				gender:"男",
				address:"花果山"
			};
			//枚举对象中的属性
			/* 
				使用 for .. in 语句
				语法:
					for(var 变量 in 对象){
						
					}
				for  ... in 语句 对象中有几个属性,循环体就会执行几次
				  每次执行时,会将对象中的一个属性的名字赋值给变量
			 */
			for(var n in obj){
				console.log("属性名: "+n);  // 属性名: name
				console.log("属性值: "+obj[n]); //属性值: 孙悟空
			}
			
		</script>

31.全局作用域

	<script type="text/javascript">
			/* 
				作用域:
				  - 作用域指一个变量的作用的范围
				  - 在JS中一共有两个作用域:
				     1.全局作用域
						- 直接编写在script标签中的JS代码,都在全局作用域
						- 全局作用域在页面打开时创建,在页面关闭时销毁
						- 在全局作用域中有一个全局对象window,他代表的是一个浏览器的窗口,
						    它由浏览器创建我们可以直接使用
						- 在全局作用域中:
							 创建的变量都会作为window对象的属性保存
							 创建的函数都会作为window对象的方法保存
						- 全局作用域中的变量都是全局变量,
								在页面的任意的部分都可以访问的到
					 
					 2.函数作用域
			 */
			
			var a = 10;
			var b= 20;
			var c = "hello";
			
			console.log(window.c);
			
			//fun(); //可以在这里提前声明调用
			//函数声明,会被提前创建
			function fun(){
				console.log("1111");
			}
			//函数表达式,不会被提前创建
			var obj2 = function fun(){
				console.log("2222");
			}
			
			fun();
			obj2();
		</script>

32.函数作用域

	<script type="text/javascript">
				/* 
					函数作用域
						- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
						- 每调用一次就会创建一个新的函数作用域,他们之间是互相独立的。
						- 在函数作用域中可以访问到全局作用域的变量
							在全局作用域中无法访问到函数作用域的变量
						- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
							  如果没有则向上一级作用域中寻找,直到找到全局作用域
							  如果全局作用域中依然没有找到,则会报错ReferenceError
					    - 在函数中要访问全局变量可以使用window对象		  
				 */
				var a = 10;
				
				function fun(){
					var a= "我是fun函数中的变量a";
					var b = 20;
					console.log("a = "+a); //我是fun函数中的变量a
					
					function fun2(){
						console.log("a = "+a); //我是fun函数中的变量a
						console.log("a = "+window.a); //a = 10
					}
					fun2();
				}
				fun();
				
				// 定义形参就相当于在函数作用域中声明了变量
				function fun4(e){
					alert(e)
				}
				fun4(); //undefined

				var w = 123;
				function fun5(){
					alert(w);  
					var w = 544;
				}
				fun5();  //undefined
				alert(w); //123
			
		</script>

33.this

<script type="text/javascript">
			/* 
				解析器在调用函数每次都会向函数内部传递一个隐函数的参数,
				  这个隐含的参数就是this,this指向的是一个对象,
				  这个对象我们称为函数执行的 上下文对象,
				  根据函数的调用方式的不同,this会指向不同的对象
				     1.以函数的形式调用时,this永远都是window
					 2.以方法的形式调用时,this就是调用方法的那个对象
			 */
			
			var name = "全局";
			function fun(){
				console.log(this.name);
			}
			//创建两个对象
			var obj = {
				name:"孙悟空",
				sayName:fun
			};
			var obj2 = {
				name:"沙和尚",
				sayName:fun
			};
			
			//fun(name); //全局
			obj.sayName(); //孙悟空
			obj2.sayName(); //沙和尚
			
		</script>

34.使用工厂方法创建对象

	<script type="text/javascript">
			
			//创建两个对象
			var obj = {
					name:"孙悟空",
					age:17,
					sayName:function(){
						alert(this.name);
					}
				};
			var obj2 = {
					name:"猪八戒",
					age:17,
					sayName:function(){
						alert(this.name);
					}
				};
			
			//obj2.sayName();	
				
			/* 
				使用工厂方法创建对象
				 通过该方法可以大批量的创建对象
			 */	
			function createPerson(name,age){
				//创建一个新对象
				var obj = new Object();
				
				//向对象中添加属性
				obj.name=name;
				obj.age = age;
				obj.sayName =function(){
					alert(this.name);
				};
				//将新的对象返回
				return obj;
			};
			
			var obj5 = createPerson("孙悟空",28);
			var obj6 = createPerson("白骨精",38);
			var obj7 = createPerson("蜘蛛精",18);
			console.log(obj5);
			console.log(obj6);
			console.log(obj7);
			obj5.sayName();
			obj6.sayName();

			/* 
				使用工厂方法创建的对象,使用的构造函数都是object
				  所以创建的对象都是object 这个类型,
				   就导致我们无法区分出多种不同类型的对象
			 */
			function createDog(name,age){
				var obj = new Object();
				obj.name=name;
				obj.age = age;
				obj.sayName =function(){
					alert("汪汪~~~");
				};
				return obj;
			};
		</script>

35.构造函数

	<script type="text/javascript">
			/* 
				创建一个构造函数,专门用来创建Person对象的
				 构造函数就是一个普通的函数,创建方式和普通函数没有区别,
				 不同的是构造函数习惯上首字母大写
				 
				构造函数和普通函数的区别就是调用方式的不同
				  普通函数是直接调用,而构造函数需要使用 new 关键字来调用
				  
				构造函数的执行流程:
				  1.立即创建一个新的对象
				  2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
				  3.逐行执行函数中的代码
				  4.将新建的对象作为返回值返回
				  
				使用同一个函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。
				   我们将通过一个构造函数创建的对象,称为是该类的实例
				   
				 this的情况:
				   1.当以函数的形式调用时,this是window
				   2.当以方法的形式调用时,谁调用方法this就是谁
				   3.当以构造函数的形式调用时,this就是新创建的那个对象
			 */
			function Person(name,age,gender){
				this.name = name,
				this.age=age,
				this.gender = gender,
				//向对象中添加一个方法
				this.sayName=function(){
					alert(this.name);
				};
				this.sayName2= fun;
			}

			// 也可以这样再外面定义一次,这样执行1000次创建,就只会执行一次
			/* 
				将sayName方法在全局作用域中定义
				  将函数定义在全局作用域,污染了全局作用域的命名空间
				   而且定义在全局作用域中也很不安全
			 */
			function fun(){
				alert(this.name);
			};
			
			function Dog(){
				
			}
			var per = new  Person("孙悟空",18,"男"); //{name: '孙悟空', age: 18, gender: '男', sayName: ƒ}
			var per2 = new  Person("白骨精",14,"女");
			var per3 = new  Person("沙和尚",19,"男");
			console.log(per);
			console.log(per2);
			console.log(per3);
			per.sayName2(); //孙悟空
			var dog = new Dog();
			console.log(dog); //Dog {}
			
			/* 
				使用instanceof可以检查一个对象是否属实一个类的实例
				语法:
					 对象 instanceof 构造函数
				如果是,则返回true,否则返回false	 
			 */
			console.log(per instanceof Person); //true
			console.log(dog instanceof Person); //false
			
			/* 
				所有的对象都是object的后代,
				  所以任何对象和object做instanceof检查时都会返回true
			 */
			console.log(per instanceof Object); //true
			console.log(dog instanceof Object); //true
		</script>

36.原型对象

	<script type="text/javascript">
			/* 
				原型 prototype
				  我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
				     这个属性对应着一个对象,这个对象就是我们所谓的原型对象
				  如果函数作为普通函数调用prototype没有任何作用
				  当函数以构造函数的形式调用时,他所创建的对象中都会有一个隐含的属性,
				      指向该构造函数的原型对象,我们可以通过 __proto__来访问该属性
					  
				  原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
						我们可以将对象中共有的内容,统一设置到原型对象中。
						
				  当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
					 如果没有则会去原型对象中寻找,如果找到则直接使用
					 
				  以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,
					    这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
			 */
			function MyClass(){
				
			}
			//向MyClass的原型中添加属性a
			MyClass.prototype.a = 123;
			
			//向MyClass的原型中添加一个方法
			MyClass.prototype.sayHello = function(){
				alert("hello");
			}
			
			var mc = new MyClass();
			var mc2 = new MyClass();
			
			//console.log(MyClass.prototype);
			//console.log(mc2.__proto__ == MyClass.prototype); //true
			
			//向mc中添加a属性
			mc.a = "我是mc中的a";
			
			console.log(mc.a); //我是mc中的a
			console.log(mc2.a);  //123
			
			//mc.sayHello();
			mc2.sayHello(); 
		</script>

image-20221230164943193

原型的补充

<script type="text/javascript">
			
			function MyClass(){
				
			}
			//向MyClass的原型中添加一个name属性
			MyClass.prototype.name = "我是原型中的名字";
			
			var mc = new MyClass();
			mc.age = 17;
			
			console.log(mc.name); //我是原型中的名字
			
			//使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
			//console.log("name" in mc); //true
			
			//可以使用hasOwnProperty()来检查对象自身是否含有该属性
			//使用该方法只有当对象自身中含有属性时,才会返回true
			console.log(mc.hasOwnProperty("name")); //false
			console.log(mc.hasOwnProperty("age"));  //true
			
			/* 
				原型对象也是对象,所以它也有原型,
				 当我们使用一个对象的属性或方法时,会出现在自身中寻找,
						自身中如果有,则直接使用,
						如果没有则去原型对象中寻找,如果原型对象中有 则使用,
						如果没有则去原型的原型中寻找,直到找到object对象的原型,
						object对象的原型没有原型,如果在object原型中依然没有找到,则返回undefined
						
			 */
			console.log(mc.__proto__.hasOwnProperty("hasOwnProperty")); //false
			console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));  //true
			
		</script>

37.toString()

<script type="text/javascript">
			function Person(name,age,gender){
							this.name = name,
							this.age=age,
							this.gender = gender
						}
			//修改person原型的toString   无论是per还是per2都会改变
				Person.prototype.toString = function(){
					return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]"
				}
						
			//创建一个person实例			
			var per = new Person("孙悟空",18,"男");
			var per2 = new Person("猪八戒",18,"男");
			
			
			//当我们直接在页面中打印一个对象时,实际上是输出的对象toString()方法的返回值
			//如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法
			//这种方法只会改变per,不会改变per2
			per.toString = function(){
				return "我是一个快乐的小person";
			}
			
			console.log(per.toString()); //[object Object]
			var result = per.toString();
			console.log(result); //[object Object]  重写toString方法后 输出:我是一个快乐的小person
			
			console.log(per);
			console.log(per2); //Person {name: '孙悟空', age: 18, gender: '男'}
			
		</script>

38.垃圾回收

	<script type="text/javascript">
			/* 
				垃圾回收(GC)
				   - 当一个对象没有任何的变量或属性对它 进行引用,此时我们将永远无法操作该对象,
					    此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
						所以这种垃圾必须进行清理。
				   - 在JS中拥有自动倒垃圾回收机制,会自动将这些垃圾对象从内存中捣毁,
						我们不需要也不能进行垃圾回收的操作
				   - 我们需要做的只是要将不再使用的对象设置null即可
			 */
			var obj = new Object();
			
			obj = null; //将不用的垃圾 设置为null , 将自动回收
			
		</script>

39.数组简介

	<script type="text/javascript">
			/* 
				数组(Array)
				 - 数组也是一个对象
				 - 它和我们普通对象功能类似,也是用来存储一些值的
				 - 不同的是普通对象是使用字符串作为属性名的,
				      而数组是使用数字来作为索引操作元素
				- 索引:
					  从0开始的整数就是索引
				- 数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据	  
			 */
			
			//创建数组对象
			var arr = new Array();
			
			//使用typeof检查一个数组时,会返回object
			console.log(typeof arr); //object
			
			/* 
				向数组中添加元素
				语法: 数组[索引] = 值
			 */
			arr[0]=10;
			arr[2]=13;
			
			console.log(arr); //[10, 空白, 13]
			/* 
				读取数组中的元素
				语法: 数组[索引]
				 如果读取不存在的索引,它不会报错而是返回undefined
			 */
			console.log(arr[0]); //10
			
			//获取数组的长度
			console.log(arr.length); //3
			
			/* 
				修改length
				 如果修改的length大于原长度,则多出部分会空出来
				 如果修改的length小于原长度,则多出的元素会被删除
			 */
			//arr.length = 10; //修改arr的length的长度为10
			
			//向数组的最后一个位置添加元素
			// 语法:数组[数组.length] = 值
			arr[arr.length] = 40;
			arr[arr.length] = 50;
			console.log(arr); // [10, 空白, 13, 40, 50]
			
		</script>

1.数组字面量

	<script type="text/javascript">
			//创建一个数组
			var arr = new Array();
			
			//使用字面量来创建数组
			//语法:[]
			var arr = [];
			console.log(arr); //[]
			console.log(typeof arr); //object
			
			//使用字面量创建数组时,可以在创建时就指定数组中的元素
			var arr = [1,3,24,4,5,3];
			 console.log(arr); //[1, 3, 24, 4, 5, 3]
			
			//使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递
			//元素之间使用,隔开
			var arr2 = new Array(10,20,30);
			console.log(arr2); //[10, 20, 30]
			
			//创建一个数组数组中只有一个元素10
			arr = [10];
			
			//创建一个长度为10的数组
			arr2 = new Array(10);
			console.log(arr2.length); //10
			
			//数组中的元素可以是任意的数据类型
			arr = ["hello",1,true,null,undefined]; //['hello', 1, true, null, undefined]
			console.log(arr);
			
			//也可以是对象
			var obj = {name:"孙悟空"};
			arr[arr.length] = obj;
			arr = [{name:"孙悟空"},{name:"沙和尚"},{name:"猪八戒"}];
			console.log(arr[1].name); //沙和尚
			
			//也可以是一个函数
			arr = [function(){alert(1)},function(){alert(2)}];
			arr[1]();
			
			//数组中也可以放数组,如下这种数组我们称为二维数组
			arr = [[1,2,3],[4,5,6],[7,8,9]];
			console.log(arr[1]); //[4, 5, 6]
			console.log(arr[0][2]); //3
			
		</script>

2.数组的四个方法

<script type="text/javascript">
			var arr  = ["孙悟空","沙和尚","猪八戒"];
			/* 
				push()
				 - 该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
				 - 可以将要添加的元素作为方法的参数传递,
						这样这些元素将会自动添加到数组的末尾
				 - 该方法会将数组新的长度作为返回值返回		
			 */
			var result = arr.push("唐僧");
			//arr.push("唐僧","白骨精",“蜘蛛精);
			console.log(arr);
			 console.log("result = " + result); //result = 4
			 
			 /* 
				pop()
				 - 该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
			 */
			arr.pop();
			result = arr.pop();
			// console.log(arr); /['孙悟空', '沙和尚']
			 console.log("result = " + result); //result = 猪八戒
			
			/* 
				unshift()
				 - 向数组开头添加一个或多个元素,并返回新的数组长度
			 */
			arr.unshift("牛魔王","二郎神");
			console.log(arr); // ['牛魔王', '二郎神', '孙悟空', '沙和尚']
			
			/* 
				shift()
				 - 可以删除数组的第一个元素,并将被删除的元素作为返回值返回
			 */
			result = arr.shift();
			console.log("result = "+ result); //result = 牛魔王
		</script>

3.forEach

<script type="text/javascript">
			var arr = ["孙悟空","猪八戒","唐僧"];
			
			/* for(var i=0;i<arr.length;i++)
				console.log(arr[i]); */
				
			/* 
				一般我们都是使用for循环去遍历数组,
				 JS中还为我们提供了一个方法,用来遍历数组 : forEach()
						这个方法只支持IE8以上的浏览器
			 */	
			/* 
				forEach()方法需要一个函数作为参数
				 - 像这种函数,由我们创建但不是由我们调用的,我们称为回调函数
				 - 数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素
						以 实参的形式传递进来,我们可以来定义形参,来读取这些内容
				 - 浏览器会在回调中传递三个参数,
					第一个参数,就是当前正在遍历的元素
					第二个参数,就是当前正在遍历的元素的索引
					第三个参数,就是正在遍历的数组
			 */
			arr.forEach(function(value,index,obj){
				console.log("value = "+value); //value = 孙悟空 ...
				console.log("index = "+index); //index = 0  ...
				console.log("obj = "+obj);  //obj = 孙悟空,猪八戒,唐僧 ...
			});
			
		</script>

4.slice 和splice

	<script type="text/javascript">
			var arr = ["孙悟空","猪八戒","唐僧","白骨精","六小龄童"];
			/* 
				slice()
				  - 可以用来从数组提取指定元素
				  - 该方法不会改变原数组,而是将截取到的元素封装到一个新数组中返回
				  - 参数:
				      1.截取开始的位置的索引,包括开始索引
					  2.截取结束的位置的索引, 不包含结束索引
						  - 第二个参数可以省略不写,此时会截取从开始索引往后的所有元素
					  - 索引可以传递一个负值, 如果传递一个负值,则从后往前计算
					      -1 倒数第一个
						  -2 倒数第二个
			 */
			console.log(arr.slice(1,3));  //['猪八戒', '唐僧']
			//console.log(arr);
			console.log(arr.slice(1,-1)); //['猪八戒', '唐僧', '白骨精']
			
			
			/* 
				splice()
				   - 可以用于删除数组中的指定元素
				   - 使用splice()会影响到原数组,会将指定元素从原数组中删除
					   并将删除的元素作为返回值返回
				   - 参数:
						  第一个: 表示开始位置的索引
						  第二个:表示删除的数量
						  第三个及以后  可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边
			 */
			
			arr = ["孙悟空","猪八戒","唐僧","白骨精","六小龄童"];
			var result = arr.splice(1,3);
			console.log(result);  //['猪八戒', '唐僧', '白骨精']
			
			var result = arr.splice(2,2,"吴京","肖战");
			console.log(arr);  // ['孙悟空', '六小龄童', '吴京', '肖战']
			
		</script>

练习

	<script type="text/javascript">
			//创建一个数组
			var arr = [1,3,2,4,2,2,2,4,1,3,5];
			
			//去除数组中重复的数字
			//获取数组中的每一个元素
			for(var i=0;i<arr.length;i++){
				//获取当前元素后的所有元素
				for(var j = i+1;j<arr.length;j++){
					//判断两个元素的值是否相等
					if(arr[i] == arr[j]){
						//如果相等则证明出现了重复的元素,则删除j对应的元素
						arr.splice(j,1);
						//当删除了当前j所在的元素之后,后边的元素会自动补位
						//此时将不会在比较这个元素了,我们需要在比较一次j所在位置的元素
						
						j--; //使j自减
					}
				}
			}
			console.log(arr);  //[1, 3, 2, 4, 5]
			
		</script>

5.数组的剩余方法

<script type="text/javascript">
			var arr = ["孙悟空","猪八戒","唐僧","白骨精","六小龄童"];
			var arr2 = ["吴京","艾佛森"];
			/* 
				concat()可以连接两个或多个数组,并将新的数组返回
					- 该方法不会对原数组产生影响
			 */
			//arr.concat(arr,arr2);
			console.log(arr.concat(arr2,"牛魔王","铁扇公主")); //['孙悟空', '猪八戒', '唐僧', '白骨精', '六小龄童', '吴京', '艾佛森', '牛魔王', '铁扇公主']

			console.log(arr); //['孙悟空', '猪八戒', '唐僧', '白骨精', '六小龄童']
			/* 
				join()
					- 该方法可以将数组转换为一个字符串
					- 该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
					- 在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
						如果不指定连接符,则默认使用,作为连接符
			 */
			var result  = arr.join("-");
			console.log(result); //孙悟空-猪八戒-唐僧-白骨精-六小龄童
			
			/* 
				reverse()
					- 该方法用来反转数组(前边的去后边,后边的去前边)
					- 该方法会直接修改原数组
			 */
			arr.reverse();
			//console.log(arr); //['六小龄童', '白骨精', '唐僧', '猪八戒', '孙悟空']
			
			/* 
				sort()
					- 可以用来对数组中的元素进行排序
					- 也会影响原数组,默认会按照Unicode编码进行排序
				
			var obj2 = ["b","v","a","e","o"];
			obj2.sort();
			console.log(obj2); //['a', 'b', 'e', 'o', 'v']
			
			/* 
				即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,
					 所以对数字进行排序时,可能会得到错误的结果
					 
				我们可以自己来指定排序的规则
					我们可以在sort()添加一个回调函数,来指定排序规则,
						回调函数中需要定义两个形参,
						浏览器将会分别使用数组中的元素来作为实参去调用回调函数
						使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边
					- 浏览器会根据回调函数的返回值来决定元素的顺序
						如果返回一个大于0的值,则元素会交换位置
						如果返回一个小于0的值,则元素位置不变
						如果返回一个0,则认为两个元素相等,也不交换位置
						
					- 如果需要升序排列,则返回 a-b
						如果需要降序排列,则返回 b-a
			 */
			
			var obj3 = [2,11,3,3,45,5,8];
			obj3.sort(function(a,b){
				//前边的大
				//这样也是升序
				/* if(a>b){
					return 1;
				}else if(a < b){
					return -1;
				}else{
					return 0;
				} */
				
				//升序
				return a-b;
				//降序
				//return b-a;
			});
			console.log(obj3);			
			
		</script>

40.Date对象

	<script type="text/javascript">
			/* 
				Date对象
					- 在JS中使用Date对象来表示一个时间
			 */
			//创建一个Date对象
			//如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间
			var d = new Date();
			
			/* 
				创建一个指定的时间对象
				需要在构造函数中传递一个表示时间的字符串作为参数
				日期的格式:  月份/日/年 时:分:秒
			 */
			var d2 = new Date("3/5/2015 12:45:55");
			console.log(d2);  //Thu Mar 05 2015 12:45:55 GMT+0800 (中国标准时间)
			/* 
				getDate()
					- 获取当前日期对象是几日
				getDay()
					- 获取当前日期对象是周几
					- 会返回一个0-6的值
					   0 表示周日
					   1 表示周一 ……
				getMonth()	   
					- 获取当前日期对象的月份
					- 会返回一个0-11的值
						0 表示 1月
						1 表示 2月
						……
						11表示 12月
						
				getFullYear()
					 - 获取当前日期对象的年份
				d2.getHours() //获取当前对象的小时
				d2.getMinutes() //获取当前对象的分钟
				d2.getSeconds() //获取当前对象的秒数
				d2.getMilliseconds()  //获取当前对象的毫秒		 
			 */
			var date = d2. getDate();
			var day = d2.getDay();
			var month = d2.getMonth();
			var year =  d2.getFullYear();
		
			console.log("date = " +date); //date = 5
			console.log("day = " + day);  //day = 4
			console.log("month = " + month);  //month = 2
			console.log("year = " + year); //year = 2015
			
			/* 
				getTime()
					- 获取当前日期对象的时间戳
					- 时间戳,指的是从格林威治标准时间的1970年1月1日,0时0分0秒
					   到当前日期所花费的毫秒数(1秒 = 1000毫秒)
					   
					- 计算机底层在保存时间时使用的都是时间戳   
			 */
			var time = d2.getTime();
			console.log(time); //1425530755000
			
			//利用时间戳来测试代码的执行的性能
			//获取当前的时间戳
			var start = Date.now();
			for(var i=0;i<1000;i++){
				console.log(i);
			}
			var end = Date.now();
			console.log("执行了:" + (end-start) + "毫秒"); //执行了:148毫秒
			
		</script>

41.Math

<script type="text/javascript">
			/* 
				Math
				  -	Math和其他的对象不同,他不是一个构造,
				      它属于一个工具类不用创建对象,它里面封装了数学运算相关的属性和方法
				  - 比如:
						Math.PI  表示圆周率
			*/
			
			console.log(Math.PI); //3.141592653589793
			
			/* 
				Math.abs() 可以用来计算一个数的绝对值
				Math.ceil() 可以对一个数进行向上取整,小数位只要有值就自动进1
				Math.floor() 可以对一个数进行向下取整,小数位部分会被舍掉
				Math.round() 可以对一个数进行四舍五入取整
				Math.random()  
					- 可以用来生成一个0-1直接的随机数
					- 生成一个0-10的随机数  比如:Math.round(Math.random()*10)
					- 生成一个0-X之间的随机数
					     Math.round(Math.random()*X)
					
					- 生成一个1-10	比如:console.log(Math.round(Math.random()*9)+1);	
					 - 生成一个x-y之间的随机数
						Math.round(Math.random()*(y-x))+x
			 */
			console.log(Math.abs(-1)); //1
			console.log(Math.ceil(1.4)); //2
			console.log(Math.floor(1.7)); //1
			console.log(Math.round(1.5)); //2
			console.log(Math.random());
			console.log(Math.round(Math.random()*10));
			console.log(Math.round(Math.random()*9)+1);
			
			/* 
				max()  可以获取多个数中的最大值
				min()  可以获取多个数中的最小值
			 */
			var max= Math.max(13,4,2,5,43,65);
			var min= Math.min(13,4,2,5,43,65);
			console.log(max); //65
			console.log(min); //2
			
			/* 
				Math.pow(x,y) 返回x的y次幂
				Math.sqrt()  用于对一个数进行开方运算
			 */
			console.log(Math.pow(4,3)); //64
			console.log(Math.sqrt(4)); //2
			
		</script>

image-20221231173838266

42.包装类

<script type="text/javascript">
			/* 
				在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
				 String()
					- 可以将基本数据类型字符串转换为String对象
				 Number()
					- 可以将基本数据类型的数字转换为Number对象
				 Boolean()
					- 可以将基本数据类型的布尔值转换为Boolean对象
				但是注意:我们在实际应用中不会使用基本数据类型的对象,
					    如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果
			 */
			
			var num = new Number(3);
			console.log(num); //3
			console.log(typeof num); //object
			
			
			/* 
				方法和属性--能添加给对象,不能添加给基本数据类型
				  当我们对一些基本数据类型的值去调用属性和方法时,
					浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法
					调用完后,在将其转换为基本数据类型
			 */
			var s = 123;
			s = s.toString();
			console.log(s); //123
			console.log(typeof s); //string
			
		</script>

43.字符串的相关方法

<script type="text/javascript">
			//创建一个字符串
			var str = "hello Atguigu";
			/* 
				在底层字符串是以字符数组的形式保存的
				["h","e",'l'...]
			 */
			console.log(str.length); //13
			console.log(str[1]); //e
			/* 
				charAt()
					- 可以返回字符串中指定位置的字符
					- 根据索引获取指定的字符
					
				charCodeAt()
					- 获取指定位置字符的字符编码(Unicode编码)
			 */
			result = str.charAt(8);
			result2 = str.charCodeAt(8);
			console.log(str);
			console.log(result); //g
			console.log(result2); //103
			
			/* 
				String.fromCharCode()
					- 可以根据字符编码去获取字符
				concat()
					- 可以用来连接两个或多个字符串
					- 作用和+一样
				indexof()
					- 该方法可以检索一个字符串是否 含有指定内容
					- 如果字符串中含有该内容,则会返回其第一次出现的索引
						如果没有找到指定的内容,则返回-1
					- 可以指定一个第二个参数,指定开始查找的位置	
				lastIndexOf()
					- 该方法的用法和indexof()一样
					   不同的是indexof是从前往后找,
					   而lastIndexOf是从后往前找
					 - 也可以指定开始查找的位置  
					
			 */
			result = String.fromCharCode(97); //a
			console.log(result);
			
			result = str.concat("你好");
			console.log(result); //hello Atguigu你好
			
			str = "hello Atguigu";
			//result = str.indexOf("o"); //4
			//result = str.indexOf("A",2); //从2开始查  看看有没有"A"
			result = str.lastIndexOf("A"); //6
			result = str.lastIndexOf("A",7); //6
			console.log(result); //4
			
			/* 
				slice()
				   - 可以从字符串中截取指定的内容
				   - 不会影响原字符串,而是将截取到内容返回
				   - 参数:
				       第一个,开始位置的索引(包括开始位置)
					   第二个,结束位置的索引(不包括结束位置)
								如果省略第二个参数,则会截取到后边所有的
						- 也可以传递一个负数作为参数,负数的话将会从后边计算		
			 */
			str = "afasasda";
			result = str.slice(1,3);//fa
			result = str.slice(1,-2); //fasas
			
			/* 
				substring()
				    - 可以用来截取一个字符串,和slice()类似
					- 参数:
						第一个,开始位置的索引(包括开始位置)
						第二个,结束位置的索引(不包括结束位置)
						- 不同的是这个方法不能接受负值作为参数,
							如果传递了一个负值,则默认使用0
						- 而且他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换			
					
			 */
			result = str.substring(1,3); //fa
			result = str.substring(1,0); //a
			result = str.substring(1,-2); //a
			console.log(result); 
			
			/* 
				split()
					- 可以将一个字符串拆分为一个数组
					- 参数:
						- 需要一个字符串作为参数,将会根据该字符串去拆分数组
					- 如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素	
			 */
			str = "sad,qr,fqw,rew";
			result = str.split(",");
			//console.log(result); //['sad', 'qr', 'fqw', 'rew']
			result = str.split("");
			console.log(result); //['s', 'a', 'd', ',', 'q', 'r', ',', 'f', 'q', 'w', ',', 'r', 'e', 'w']
			console.log(result.length); //4
			console.log(result[1]); //qr
			
			/* 
				toUpperCase()
					- 将一个字符串转换为大写并返回,   不会影响原字符串
				toLowerCase()
					- 将一个字符串转换为小写并返回
			 */
			str = "afAasd";
			result = str.toUpperCase(); //AFAASD
			//result = str.toLowerCase(); //afaasd
			console.log(result);
			
		</script>

44.正则表达式的简介

				/* 
					正则表达式
					    - admin@atgui.com
						-邮件的规则:
							1.前边可以是xxxx
							2.跟着一个@
							3.后边可以是xxxx
							4. .com获取其他的
							
						- 正则表达式用于定义一些字符串的规则,
							 计算机可以根据正则表达式,来检查一个字符串是否符合规则,
							  获取将字符串中符合规则的内容提取出来
				 */
			
			//创建正则表达式对象
			/* 
				语法:
					var 变量= new RegExp("正则表达式","匹配模式");
					使用typeof检查正则对象,会返回object
					var reg = new RegExp("asda"); 这个正则表达式可以来检查一个字符串是否含有asda
				 在构造函数中可以传递一个匹配模式作为第二个参数,
					 可以是  i 忽略大小写
							 g  全局匹配模式
					
				正则表达式的方法:
					test()
					   - 使用这个方法可以用来检查一个字符串是否符合正则表达式的规则
							如果符合则返回true,否则返回false
			 */
			var reg = new RegExp("asda");
			//var reg = new RegExp("asda",i);
			//console.log(reg); ///asda/
			//console.log(typeof reg); //object
			var str = "asda";
			result = reg.test(str);
			console.log(result);
			
		</script>

1.正则语法

<script type="text/javascript">
			/* 
				使用字面量来创建正则表达式
				  语法: var 变量= /正则表达式/匹配模式
				  
			 */
			//var reg = new RegExp("a","i");
			var reg = /a/i;
			console.log(reg.test("avc")); //true
			
			//创建一个正则表达式,检查一个字符串中是否含有a或b
			//  使用 |表示或者的意思
			reg = /a|b/;
			console.log(reg.test("adsd"));
			
			//创建一个正则表达式检查一个字符串中是否含有字母
			// []里的内容也是或的关系
			//  [ab] == a|b
			// [a-z] 任意的小写字母
			// [A-Z]  任意的大写字母
			// [A-z] 任意字母
			// [0-9] 任意数字
			reg = /[a-z]/;
			console.log(reg.test("adsd"));
			
			//检查一个字符串中是否含有abc 或adc或aec
			reg = /a[bde]c/
			
			// [^ ] 表示 除了
			reg = /[^ab]/;
			reg = /[0-9]/;
			console.log(reg.test("abvc"));
			
		</script>

2.字符串和正则相关的方法

<script type="text/javascript">
				/* 
					split()
						- 可以将一个字符串拆分为一个数组
						- 方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串
						- 这个方法即使不指定全局匹配,也会全都拆分
				 */
				var str = "1a2b3c4d5e6f7";
				//根据任意字母来将字符串拆分
				var result = str.split(/[A-z]/); //['1', '2', '3', '4', '5', '6', '7']
				console.log(result)
				
				/* 
					search()
					    - 可以搜索字符串中是否含有指定内容
						- 如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1
						- 它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
						- search()只会查找第一个,即使设置全局匹配也没用
				*/
			   str = "hello abc hello aec afc";
			   //搜索字符串中是否含有abc aec afc
			   result = str.search(/a[bef]c/); //6
			   console.log(result);
			   
			   /* 
				    match()
						- 可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
						- 默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
						    我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
							可以为一个正则表达式设置多个匹配模式,且顺序无所谓
						- match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果	
			   */
			   str = "1a2b3c4d5e6f7A8B9a";
			   result = str.match(/[A-z]/g); //['a', 'b', 'c', 'd', 'e', 'f']
			    result = str.match(/[a-z]/gi); //['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B']
			   console.log(result);
			
			/* 
				replace()
					- 可以将字符串中指定内容替换为新的内容
					- 参数:
						1. 被替换的内容 , 可以接收一个正则表达式作为参数
						2. 新的内容
					- 默认只会替换一个	
			 */
			//result = str.replace("a","@_@");  //1@_@2b3c4d5e6f7A8B
			result = str.replace(/a/g,"@_@"); //1@_@2b3c4d5e6f7A8B9@_@
			result = str.replace(/[a-z]/gi,"");  //123456789  将所有的字母删除
			console.log(result);
			
		</script>

3.正则表达式语法

<script type="text/javascript">
			/* 
				量词:
				  - 通过量词可以设置一个内容出现的次数
				  - 量词只对它前边的一个内容起作用
				  - {n} 正好出现n次
				  - {m,n} 出现m-n次
				  - {m,}  出现m次以上
				  -  + 至少一个,相当于{1,}
				  -  * 0个或多个,相当于{0,}
				  -  ? 0个或1个 ,相当于{0,1}
			 */
			var reg = /a{3}/;
			//ababab
			reg = /(ab){3}/;
			console.log(reg.test("abababa"));
			reg = /ab{2,3}c/; //b出现2-3次
			reg = /ab{2,}c/; //b出现2次以上
			reg = /ab+c/; 
			reg = /ab*c/; 
			reg = /ab?c/; 
			console.log(reg.test("abbc"));
			
			/* 
				检查一个字符串是否以a开头
				  ^  表示开头 , 在[^]中表示 ,除了
				  $ 表示结尾
			 */
			reg = /^a/; //匹配开头的a
			reg = /a$/;  //匹配结尾的a
			console.log(reg.test("asa"));
			//如果在正则表达式中同时使用  ^ $则要求字符串必须完全符合正则表达式
			reg = /^a$/;  //表示必须以a开头,立刻又以a结尾
			reg = /^a|a$/; //以a开头,或以a结尾
			console.log(reg.test("2asaww"));
			
			/* 
				创建一个正则表达式,用来检查一个字符串是否是一个合法手机号
				
				手机号的规则:
					1 3 567890123 (11位)
				   1. 以 1 开头
				   2. 第二位3-9任意数字
				   3. 三位以后任意数字9个
				   ^1 [3-9] [0-9]{9}$
			 */
			var phonestr = "13567890123"
			var phoneReg = /^1[3-9][0-9]{9}/;
			console.log(phoneReg.test(phonestr));  //true
			
			/* 
				检查一个字符串中是否含有.
				. 表示任意字符
				在正则表达式中使用\ 作为转义字符
				\. 来表示.
			 */
			var reg = /\./;
			console.log(reg.test("asd."));
			
			/* 
				\w  表示 任意字母 、数字、_   [A-z0-9_]
				\W  表示  除了字母、数字、 _   [^A-z0-9_]
				\d  表示  任意的数字  [0-9]
				\D  表示  除了数字  [^0-9]
				\s  表示  空格
				\S  表示  除了空格
				\b  表示  单词边界
				\B  表示  除了单词边界
			 */
			var reg = /\w/;
			
			//创建一个正则表达式检查一个字符串中是否含有单词child
			reg = /\bchild\b/;
			console.log(reg.test("ads childaqe")); //false
			console.log(reg.test("ads child aqe")); //true
			
			var  str = "      sdas  dsa         ";
			//去除掉字符串中的前后的空格
			//去除空格就是使用"来替换空格
			//str = str.replace(/\s/g,"");
			//console.log(str);  //sdasdsa
			
			//去除开头的空格
			//str = str.replace(/^\s*/,"")
			//去除结尾的空格
			//str = str.replace(/\s*$/,"")
			//  ^\s*|\s*$   匹配开头和结尾的空格
			str = str.replace(/^\s*|\s*$/g,"");  //sdas  dsa
			console.log(str);  
			
		</script>

练习

	<script type="text/javascript">
			
			/* 
				电子邮件的正则:
					hello  .nihao   @  abc  .com.cn
				任意字母数字下划线   .任意字母数字下划线 @ 任意字母数字  .任意字母(2-5位) .任意字母(2-5位)
				
				\w{3,} (\.\w+)*  @  [A-z0-9]+  (\.[A-z]{2,5}){1,2} 
			 */
			var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
			var email = "abc@abc.com.as";
			console.log(emailReg.test(email));
			
		</script>

45.DOM简介

image-20221231224701646

image-20221231224726124

image-20221231224739932

	<body>
		<button id="btn">我是一个按钮</button>
		<script type="text/javascript">
			/* 
				浏览器已经为我们提供文档结点对象这个对象是window属性
				可以在页面中直接使用,文档结点代表的是整个页面
			 */
			//console.log(document);
			
			//获取到button对象
			var btn = document.getElementById("btn");
			//修改按钮的文字
			btn.innerHTML = "I am a button"
		</script>

46.事件的简介

<body>
		<!-- 
			我们可以在事件对应的属性中设置一些js代码,
				这样当事件被触发时,这些代码将会执行
			这种写法我们称为结构和行为耦合,不方便维护,不推荐使用	
		 -->
		 <!-- <button id= "btn" onclick="alert('点我干嘛!');">我是一个按钮</button> -->
		 <button id="btn">我是一个按钮</button>
		 <script type="text/javascript">
		 	/* 
				事件,就是用户和浏览器之间的交互行为,
				    比如 : 点击按钮,鼠标移动,关闭窗口。。。
			 */
			//获取按钮对象
			var btn = document.getElementById("btn");
			/* 
				可以为按钮的对应时间绑定处理函数的形式来响应事件
					这样当事件被触发时,其对应的函数将会被调用
			 */
			
			//绑定一个单击事件
			//像这种为单击事件绑定的函数,我们称为单击响应函数
			btn.onmousemove = function(){
				alert("你还点击我~~~");
			};
			
		 </script>
		 
	</body>

47.文档的加载

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			/* 
				onload事件会在整个页面加载完成之后才触发
				 为window绑定一个onload事件
						该事件对应的响应函数将会在页面加载完成之后执行
						这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了
			 */
			window.onload = function(){
				var btn = document.getElementById("btn");
				btn.onclick = function(){
					alert("hello");
				};
			};
			
		</script>
	</head>
	<body>
		<button type="button" id="btn">我是一个按钮</button>
	</body>
</html>

image-20221231232821308

1.获取元素结点

image-20230101104019203

image-20230101104043336

2.获取元素结点的子节点

image-20230101104121991

练习

image-20230101104311516

image-20230101104333686

image-20230101104353199

image-20230101104454871

3.获取父节点和兄弟结点

image-20230101105749858

4.dom查询的剩余方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			window.onload = function(){
				//获取body标签
				//var body = document.getElementsByTagName("body")[0];
				
				//在document中有一个属性body,它保存的是body的引用
				var body = document.body;
				
				//document.documentElement保存的是html根标签
				var html = document.documentElement;
				
				//document.all代表页面中所有的元素
				var all = document.all;
				all = document.getElementsByTagName("*") //HTMLCollection(6) [html, head, meta, title, script, body]
				console.log(all);
				
				//获取class为box1中的所有的div
				/* 
					document.querySelector()
						- 需要一个选择器的字符串作为参数,可以根据一个css选择器来查询一个元素结点对象
						- 虽然IE8中没有getElementsByClassName()但是可以使用querySelector()代替
						- 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
				 */
				var div  = document.querySelector(".box1  div");
				console.log(div.innerHTML);
				
				/* 
					document.querySelectorAll()
						- 该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回
						- 即使符合条件的元素只有一个,他也会返回数组
				 */
				var box1 = document.querySelectorAll(".box1 ");
				console.log(box1.length);  //2
			}
			
		</script>
	</head>
	<body>
		<div class="box1">
			<div >我是box1中的div</div>
			<div>11</div>
		</div>
		<div class="box1">
			<div >我是box1中的div</div>
			<div>12</div>
		</div>
		<div></div>
	</body>
</html>

练习

image-20230101105842015

image-20230101105858795

image-20230101105909256

image-20230101105926011

image-20230101105941856

1.图片切换的练习

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			img{
				width: 500px;
				height: 350px;
			}
			#outer{
				width: 500px;
				margin: 50px auto;
				background-color: blue;
				padding: 10px;
				//设置文本居中
				text-align: center;
				
			}
			p{
				text-align: center;
			}
			
		</style>
		
		<script type="text/javascript">
			window.onload = function(){
				/* 
					点击切换图片
				 */
				//获取两个按钮
				var prev = document.getElementById("prev");
				var next = document.getElementById("next");
				//获取img标签
				var img = document.getElementsByTagName("img")[0];

				//创建一个数组,用来保存图片的路径
				var imgArr = ["img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg"];
				//创建一个变量,来保存当前正在显示的图片的索引
				var index= 0;
				
				//获取id为info的p元素
				var info = document.getElementById("info");
				//设置提示文字
				info.innerHTML = "一共"+imgArr.length+"张图片,当前第"+(index+1)+"张";
				
				//分别为两个按钮绑定单击响应函数
				prev.onclick = function(){
					//alert("11");
					index--;
					//判断index是否小于0
					if(index < 0){
						//index  = 0;
						index  = imgArr.length-1;
					}
					img.src = imgArr[index];
					//当点击按钮以后,重新设置信息
					info.innerHTML = "一共"+imgArr.length+"张图片,当前第"+(index+1)+"张";
				}
				next.onclick = function(){
					//alert("22");
					
					index++;
					if(index > imgArr.length-1){
						//index  = imgArr.length-1;
						index  = 0;
					}
					//切换图片就是修改img的src属性
					//要修改一个元素的属性  元素.属性= 属性值
					img.src = imgArr[index];
					info.innerHTML = "一共"+imgArr.length+"张图片,当前第"+(index+1)+"张";
				}
			};
			
		</script>
		
	</head>
	<body>
		<div id="outer">
			<p id= "info"></p>
			<img src="img/1.jpg" alt="美图" />
			<button id="prev">上一张</button>
			<button id="next">下一张</button>
			
		</div>
	</body>
</html>

示例:

image-20230101102427010

2.全选练习

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>全选练习</title>
		<script type="text/javascript">
			window.onload = function(){
				/* 
					全选按钮
						- 点击按钮以后,四个多选框全都被选中
				 */
				var checkedAllBtn = document.getElementById("checkedAllBtn");
				checkedAllBtn.onclick = function(){
						//alert("11");
					var items = document.getElementsByName("items");
					for(var i=0;i<items.length;i++){
						//通过多选框的checked属性可以来获取或设置多选框的选中状态
						//设置四个多选框变成选中状态
						items[i].checked = true;
					}
					
					//将全选/全不选设置为选中
					checkedAllBox.checked = true;
				};
				
				/*
					全不选按钮
						- 点击按钮以后,四个多选框都变成没选中的状态
				 */
				var checkedNoBtn = document.getElementById("checkedNoBtn");
				checkedNoBtn.onclick = function(){
					var items = document.getElementsByName("items");
					for(var i=0;i<items.length;i++){
						//设置四个多选框设置成未选中状态
						items[i].checked = false;
					}
					
					//将全选/全不选设置为不选中
					checkedAllBox.checked = false;
				};
				
				//反选按钮
				// 点击按钮以后,选中的变成没选中,没选中的编程选中
				var checkedRevBtn = document.getElementById("checkedRevBtn");
				checkedRevBtn.onclick = function(){
					var items = document.getElementsByName("items");
					checkedAllBox.checked = true;
					for(var i=0;i<items.length;i++){
						// if(items[i].checked == false){
						// 	items[i].checked = true;
						// }else{
						// 	items[i].checked = false;
						// }
						//或者
						     items[i].checked = !items[i].checked;
						
						//判断四个多选框是否全选
						//只要有一个没选中则就不是全选
						if(!items[i].checked){
							//一旦进入判断,则证明不是全选状态
							//将checkedAllBox设置为没选中状态
							checkedAllBox.checked = false;
						}
					}
				};
				
				
				//提交按钮
				//  点击按钮后,将所有选中的多选框的value属性值弹出
				var sendBtn = document.getElementById("sendBtn");
				sendBtn.onclick = function(){
					var items = document.getElementsByName("items");
					for(var i=0;i<items.length;i++){
						if(items[i].checked == true){
							alert(items[i].value);
						}
					}
				};
				
				//全选/全不选按钮
				//在事件的响应函数中,响应函数是给谁绑定的this就是谁
				var checkedAllBox = document.getElementById("checkedAllBox");
				checkedAllBox.onclick = function(){
					var items = document.getElementsByName("items");
					//alert(this === checkedAllBox) //true
					//设置多选框的选中状态
					for(var i=0;i<items.length;i++){
						//items[i].checked = checkedAllBox.checked;
						items[i].checked = this.checked; //与上面语句等价
					}
				};
				
				//如果四个多选框全选中,则checkedALLBox也应该选中
				//如果四个多选框没都选中,则checkedALLBox也不应该选中
				
				//为四个多选框分别绑定单击响应函数
				var items = document.getElementsByName("items");
				for(var i=0;i<items.length;i++){
					items[i].onclick = function(){
						//将checkedAllBox设置为选中状态
						checkedAllBox.checked = true;
						for(var j=0;j<items.length;j++){
							//判断四个多选框是否全选
							//只要有一个没选中则就不是全选
							if(!items[j].checked){
								//一旦进入判断,则证明不是全选状态
								//将checkedAllBox设置为没选中状态
								checkedAllBox.checked = false;
								break;
							}
						}
					};
				}
				
			};
			
		</script>
	</head>
	<body>
		
		<form action="" method="post">
			你爱好的运动是?<input type="checkbox" id="checkedAllBox"  />全选/全不选
			<br>
			<input type="checkbox" name="items" value="足球" />足球
			<input type="checkbox" name="items" value="篮球" />篮球
			<input type="checkbox" name="items" value="羽毛球" />羽毛球
			<input type="checkbox" name="items" value="乒乓球" />乒乓球
			<br>
			<input type="button" id="checkedAllBtn" value="全 选" />
			<input type="button" id="checkedNoBtn" value="全不选" />
			<input type="button" id="checkedRevBtn" value="反 选" />
			<input type="button" id="sendBtn" value="提  交" />
		</form>
		
	</body>
</html>

image-20230101133613226

image-20230101133630642

5.dom的增删改

image-20230101153556441

image-20230101153622250

image-20230101153646625

image-20230101153702370

image-20230101153715401

image-20230101153734061

image-20230101153748711

image-20230101153813824

6.操作内联样式(使用DOM操作css)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 100px ;
				height: 100px ;
				background-color: red;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				//点击按钮以后,修改box1的大小
				//获取box1
				var box1 = document.getElementById("box1");
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					//修改box1的宽度
					/* 
						通过JS修改元素的样式
						 语法: 元素.style.样式名 = 样式值
						 
						 注意:如果CSS的样式名中含有 -
							 这种名称在JS中是不合法的比如 background-color
							 需要将这种样式名修改wi驼峰命名法, 去掉-,然后将-后的字母大写
							 
						我们通过style属性设置的样式都是内联样式,
							而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
							
						但是如果在样式中写了 !important,则此时样式会有最高的优先级,
							即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效
							所以尽量不要为样式添加!important
							比如 background-color: red !important;
					 */
					box1.style.width= "400px";
					box1.style.backgroundColor = "green"
				};
				
				//点击按钮2以后,读取元素的样式
				var btn02 = document.getElementById("btn02");
				btn02.onclick = function(){
					//读取box1的样式
					/* 
						语法:  元素.style.样式名
						
						通过style属性设置和读取的都是内联样式
						   无法读取样式表中的样式
					 */  
					alert(box1.style.width);
				};
				
			};
						
		</script>
	</head>
	<body>
		<button type="button" id= "btn01">点击切换颜色</button>
		<button type="button" id= "btn02">点击读取元素样式</button>
		<br />
		<div id="box1">			
		</div>		
	</body>
</html>

7.获取当前元素的样式 (getStyle()方法)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 100px;
				height: 100px;
				background-color: red;
			}
		</style>
		<script type="text/javascript">
		
			window.onload = function(){
				var box1 = document.getElementById("box1");
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					/* 
						获取元素的当前显示的样式
						  语法:  元素.currentStyle.样式名
						 它可以用来读取当前元素正在显示的样式 
						  如果当前元素没有设置该样式,则获取它的默认值
						  
						currentStyle 只有IE浏览器支持,其他的浏览器不支持  
					 */
					// alert(box1.currentStyle.width);
					
					/* 
						在其他浏览器中可以使用
							getComputedStyle()这个方法来获取当前的样式
							这个方法是window的方法,可以直接使用
						  需要两个参数:
							    第一个:  要获取样式的元素
								第二个   可以传递一个伪元素, 一般都传null
						该方法会返回一个对象,对象中封装了当前元素对应的样式		
							可以通过对象.样式名来读取样式
							如果获取的样式没有设置,则会获取到真实的值,而不是默认值
							比如,没有设置width,它不会获取到auto,而是一个长度
							
						但是该方法不支持IE8及以下的浏览器	
						
						通过currentStyle和getComputedStyle()读取到的样式都是只读的,
							不能修改,如果要修改必须通过style属性
					 */
					
					//var obj = getComputedStyle(box1,null);
					//alert(obj.width);
					
					
					alert(getStyle(box1,"backgroundColor"));
					alert(getStyle(box1,"width"));
				};
				
				
				/* 
					定义一个函数,用来获取指定元素的当前的样式
					参数;
						obj 要获取样式的元素
						name  要获取的样式名
				 */
				function getStyle(obj,name){
					if(window.getComputedStyle){
						//正常浏览器的方式 , 具有getComputedStyle()方法
						return getComputedStyle(obj,null)[name];
					}else{
						//IE8的方式 ,没有getComputedStyle()方法
						return obj.currentStyle[name];
					}
				};
			};
			
		</script>
	</head>
	<body>
		<button type="button" id="btn01">点我一下</button>
		<div id="box1" style="width: 200px;">
		</div>
	</body>
</html>

8.其它样式相关的属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 100px;
				height: 100px;
				background-color: red;
				padding: 10px;
				border: 12px solid yellow;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				var box1 = document.getElementById("box1");
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					/* 
						clientWidth
						clientHeight
							- 这两个属性可以获取元素的可见宽度和高度
							- 这些属性都是不带px的,返回都是一个数字,可以直接进行计算
							- 会获取元素宽度和高度,包括内容区和内边距
							- 这些属性都是只读的,不能修改
					*/
					alert(box1.clientWidth);
					/* 
						offsetHeight和offsetWidth
							- 获取元素的整个的宽度和高度,包括内容区。内边距和边框
					 */
					alert(box1.offsetHeight);
					
					/* 
						offsetParent
							- 可以用来获取当前元素的定位父元素
							- 会获取到离当前元素最近的开启了定位的祖先元素
								如果所有的祖先元素都没有开启定位,则返回body
					 */
					var op = box1.offsetParent;
					//alert(op.id)
					
					/* 
						offsetLeft
							- 当前元素相对于其定位元素的水平偏移量
						offsetTop
							- 当前元素相对于其定位元素的垂直偏移量
					 */
					alert(box1.offsetLeft);
					
					/* 
						scrollHeight
						scrollWidth
							- 可以获取元素整个滚动区域的宽度和高度
							
						scrollLeft
							- 可以获取水平滚动条滚动的距离
						scrollTop
							- 可以获取垂直滚动条滚动的距离
					 */
					alert(box1.scrollWidth);
					box1.scrollTop
					
					//当满足scrollHeight - scrollTop ==clientHeight
					// 说明垂直滚动条滚动到底了
					alert(box1.scrollHeight - box1.scrollTop)
					
					//当满足scrollWidth - scrollTop ==clientWidth
					// 说明水平滚动条滚动到底了
					alert(box1.scrollWidth - box1.scrollTop)
				};
			}
		</script>
	</head>
	<body>
		<button type="button" id="btn01">点我一下</button><br /><br />
		<div id="box1" >
		</div>
	</body>
</html>

练习(当垂直滚动条滚动到底时使表单项可用)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#info{
				width: 140px;
				height: 400px;
				border: 1px solid #FFFF00;
				overflow: auto;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				/*
					当垂直滚动条滚动到底时使表单项可用
					onscroll
						- 该事件会在元素的滚动条滚动时触发
				 */
				//获取id为info的p元素
				var info = document.getElementById("info");
				//获取两个表单项
				var inputs = document.getElementsByTagName("input");
				info.onscroll = function(){
					//alert("我滚动了");
					//检查垂直滚动条是否滚动到底
					if(info.scrollHeight-info.scrollTop == info.clientHeight){
						//滚动条滚动到底,使表单项可用
						/* 
						  disabled属性可以设置一个元素是否禁用
						   如果设置为true,则元素禁用
						   如果设置为false,则元素可用
						 */
						inputs[0].disabled = false;
						inputs[1].disabled = false;
					}
				}
			};
			
		</script>
	</head>
	<body>
		<h3>欢迎亲爱的用户注册</h3>
		<p id = "info">
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
			亲爱的用户,请先阅读目录详情
		</p>
		<input type="checkbox" disabled="disabled" /> 我已仔细阅读协议,一定遵守
		<input type="submit" value="注册" disabled="disabled" />
	</body>
</html>

49.事件对象

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style type="text/css">
			#areaDiv{
				width: 150px;
				height: 40px;
				border: 1px solid black;
			}
			#showMsg{
				width: 100px;
				height: 40px;
				border: 1px solid black;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				/*
					当鼠标在areaDiv中移动时,在showMsg中来显示鼠标的坐标
				 */
				var areaDiv = document.getElementById("areaDiv");
				var showMsg = document.getElementById("showMsg");
				
				/* 
					onmousemove
						- 该事件将会在鼠标 在元素中移动时被触发
						
					事件对象
						- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,
						   在事件对象中封装了当事件相关的一切信息,比如:鼠标的坐标,键盘那个按键被按下  鼠标滚轮的方向....
				 */
					areaDiv.onmousemove = function(event){
						/* 
						在IE8中,响应函数被触发时,浏览器不会传递事件对象,
						  在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的
						 */
						if(!event){
							 event = window.event;
						}
						// 或者  解决事件对象的兼容性问题(和上面效果相同)
						event = event || window.event;
						/* 
							clientX 可以获取鼠标指针的水平坐标 
							clientY 可以获取鼠标指针的垂直坐标 
						 */
						var x = event.clientX;
						var y = event.clientY;
						//alert("x= "+x);
						//在showMsg中来显示鼠标的坐标
						showMsg.innerHTML = "x= "+x+",y="+y;
					};
			};
		</script>
	</head>
	<body>
		<div id="areaDiv"></div><br />
		<div id="showMsg"></div>
	</body>
</html>

image-20230101193804135

50.div跟随鼠标移动

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 150px;
				height: 100px;
				background-color: red;
				//开启box1的绝对定位
				position: absolute;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				//使div可以跟随鼠标移动
				
				var box1 = document.getElementById("box1");
				document.onmousemove = function(event){
					//解决兼容性问题
					event = event | window.event;
					
					/* 
						获取滚动条滚动的距离
						 谷歌浏览器认为滚动条是body的,可以通过body.scrollTop来获取
						 火狐等浏览器认为浏览器的滚动条是html的
					 */
					var st = document.body.scrollTop ||document.documentElement.scrollTop;
					var sl = document.body.scrollLeft ||document.documentElement.scrollLeft;
					
					//获取到鼠标的位置
					/* 
						clientX和clientY
						   用于获取鼠标在当前可见窗口的坐标
						div的偏移量,是相对于整个页面的
						
						pageX和pageY 可以获得鼠标相对于当前页面的坐标
							但是这个属性在IE8中不支持
					 */
					// var left = event.pageX;
					// var top = event.pageY;
					var left = event.clientX;
					var top = event.clientY;
					//设置div的偏移量
					box1.style.left = left +sl+ "px";
					box1.style.top = top + st+ "px";
					
				};
				
			};
			
		</script>
	</head>
	<body style="height: 1000px;">
		<div id="box1">
			
		</div>
	</body>
</html>

51.事件的冒泡

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1{
				width: 200px;
				height: 200px;
				background-color: yellowgreen;
			}
			#s1{
				background-color: aqua;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				/* 
					事件的冒泡
						- 所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
						- 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
				 */
				
				//为s1绑定一个单击响应函数
				var s1 = document.getElementById("s1");
				s1.onclick = function(event){
					event = event || window.event;
					alert("span");
					//取消冒泡
					//可以将事件对象的cancelBubble设置为true,即可取消冒泡
					event.cancelBubble =true;
				};
					
				//为box1绑定一个单击响应函数
				var box1 = document.getElementById("box1");
				box1.onclick = function(){
					alert("box1");
				};
				//为body绑定一个单击响应函数
				var body = document.getElementById("body");
				document.body.onclick = function(){
					alert("body");
				};
				
			}
			
		</script>
	</head>
	<body>
		<div id="box1">
			我是box1
			<span id="s1">我是span</span>
		</div>
	</body>
</html>

image-20230101211642201

52.事件的委派

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			window.onload = function(){
				var u1 = document.getElementById("u1");
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					var li = document.createElement("li");
					li.innerHTML = "<a href='javascript:;' class='link'>新建的超链接</a>"
					u1.appendChild(li);
				};
				/* 
					事件的委派
						- 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素
							从而通过祖先元素的响应函数来处理事件
						- 事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能	
				 */
				//为u1绑定一个单击响应函数
				u1.onclick = function(event){
					event = event || window.event;
					/* 
						target
							- event中的target表示的触发事件的对象
					 */
					//alert(event.target);
					//如果触发事件的对象是我们期望的元素,则执行否则不执行
					if(event.target.className == "link"){
							alert("我是u1的单击响应函数");
					}
				}
				
			}
			
		</script>
	</head>
	<body>
		<button type="button" id="btn01">添加超链接</button>
		<ul id="u1">
			<li><a href="javascript:;" class="link">超链接一</a></li>
			<li><a href="javascript:;" class="link">超链接二</a></li>
			<li><a href="javascript:;" class="link">超链接三</a></li>
		</ul>
	</body>
</html>

image-20230101214210365

53.事件的绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			window.onload = function(){
				var btn01 = document.getElementById("btn01");
				/* 
					addEventListener()
						- 通过这个方法也可以为元素绑定响应函数
						- 参数:
							1.事件的字符串,不用on
							2.回调函数,当事件触发时该函数会被调用
							3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
							
					使用addEventListener	()可以同时为一个元素的相同事件同时绑定多个响应函数,
						 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
						 
					这个方法不支持IE8及以下的浏览器	 
				 */
				btn01.addEventListener("click",function(){
					alert("1");
				},false);
				btn01.addEventListener("click",function(){
					alert("2");
				},false);
				btn01.addEventListener("click",function(){
					alert("3");
				},false);
				
				/* 
					attachEvent()
						- IE8中可以使用attachEvent()来绑定事件
						- 参数:
							 1.事件的字符串,要on
							 2. 回调函数
						
						- 这个方法也可以同时为一个事件绑定多个处理函数,
							 不同的是它是后绑定先执行,执行顺序和addEventListener()相反
				 */
				btn01.attachEvent("onclick",function(){
					alert("1");
				});
				btn01.attachEvent("onclick",function(){
					alert("2");
				});
				
				bind(btn01,"click",function(){
					alert("1");
				})
				
				//定义一个函数,用来为指定元素绑定响应函数  
				/*  
							 * addEventListener()中的this,是绑定事件的对象  
							 * attachEvent()中的this,是window  
							 *  需要统一两个方法this  
							 */  
				/*  
							 * 参数:  
							 * 	obj 要绑定事件的对象  
							 * 	eventStr 事件的字符串(不要on)  
							 *  callback 回调函数  
							 */  
				function bind(obj , eventStr , callback){  
				    if(obj.addEventListener){  
				        //大部分浏览器兼容的方式  
				        obj.addEventListener(eventStr , callback , false);  
				    }else{  
							/*  
							* this是谁由调用方式决定  
							* callback.call(obj)  
							*/  
				        //IE8及以下  
				        obj.attachEvent("on"+eventStr , function(){  
				            //在匿名函数中调用回调函数  
				            callback.call(obj);  
				        });  
				    }  
				}  
			}
			
		</script>
	</head>
	<body>
		<button type="button" id="btn01">单击按钮</button>
	</body>
</html>

image-20230101220822689

54.事件的传播(了解即可)

关于事件的传播网景公司和微软公司有不同的理解
微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,
然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,
然后在向内传播给后代元素
W3C综合了两个公司的方案,将事件传播分成了三个阶段
1.捕获阶段
在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段
事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件

如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false

IE8及以下的浏览器中没有捕获阶段

image-20230101221619029

55.拖拽

<!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
        <title></title>  
<style type="text/css">  
  
    #box1{  
	width: 100px;  
	height: 100px;  
	background-color: red;  
	position: absolute;  
	}  
	  
	#box2{  
	width: 100px;  
	height: 100px;  
	background-color: yellow;  
	position: absolute;  
	  
	left: 200px;  
	top: 200px;  
	}  
  
    </style>  
  
<script type="text/javascript">  
  
    window.onload = function(){  
				/*  
				 * 拖拽box1元素  
				 *  - 拖拽的流程  
				 * 		1.当鼠标在被拖拽元素上按下时,开始拖拽  onmousedown  
				 * 		2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove  
				 * 		3.当鼠标松开时,被拖拽元素固定在当前位置	onmouseup  
				 */  
  
				//获取box1  
				var box1 = document.getElementById("box1");  
				var box2 = document.getElementById("box2");  
				var img1 = document.getElementById("img1");  
			  
				//开启box1的拖拽  
				drag(box1);  
				//开启box2的  
				drag(box2);  
			  
				drag(img1);  
  
};  
  
			/*  
			 * 提取一个专门用来设置拖拽的函数  
			 * 参数:开启拖拽的元素  
			 */  
function drag(obj){  
    //当鼠标在被拖拽元素上按下时,开始拖拽  onmousedown  
    obj.onmousedown = function(event){  
  
        //设置box1捕获所有鼠标按下的事件  
        /*  
					 * setCapture()  
					 * 	- 只有IE支持,但是在火狐中调用时不会报错,  
					 * 		而如果使用chrome调用,会报错  
					 */  
					/*if(box1.setCapture){  
						box1.setCapture();  
					}*/  
        obj.setCapture && obj.setCapture();  
  
  
        event = event || window.event;  
        //div的偏移量 鼠标.clentX - 元素.offsetLeft  
        //div的偏移量 鼠标.clentY - 元素.offsetTop  
        var ol = event.clientX - obj.offsetLeft;  
        var ot = event.clientY - obj.offsetTop;  
  
  
        //为document绑定一个onmousemove事件  
        document.onmousemove = function(event){  
            event = event || window.event;  
            //当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove  
            //获取鼠标的坐标  
            var left = event.clientX - ol;  
            var top = event.clientY - ot;  
  
            //修改box1的位置  
            obj.style.left = left+"px";  
            obj.style.top = top+"px";  
  
        };  
  
        //为document绑定一个鼠标松开事件  
        document.onmouseup = function(){  
            //当鼠标松开时,被拖拽元素固定在当前位置	onmouseup  
            //取消document的onmousemove事件  
            document.onmousemove = null;  
            //取消document的onmouseup事件  
            document.onmouseup = null;  
            //当鼠标松开时,取消对事件的捕获  
            obj.releaseCapture && obj.releaseCapture();  
        };  
  
 /*  
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,  
* 	此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,  
* 	如果不希望发生这个行为,则可以通过return false来取消默认行为  
*   
* 但是这招对IE8不起作用  
*/  
        return false;  
    };  
}  
  
  
</script>  
</head>  
<body>  
  
    我是一段文字  
  
<div id="box1"></div>  
  
<div id="box2"></div>  
  
<img src="img/an.jpg" id="img1" style="position: absolute;"/>  
    </body>  
</html>  

image-20230101231125199

56.滚轮的事件

<!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
        <title></title>  
<style type="text/css">  
  
    #box1{  
width: 100px;  
height: 100px;  
background-color: red;  
}  
  
    </style>  
<script type="text/javascript">  
  
    window.onload = function(){  
  
  
    //获取id为box1的div  
    var box1 = document.getElementById("box1");  
  
                //为box1绑定一个鼠标滚轮滚动的事件  
                /*  
				 * onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,  
				 * 	但是火狐不支持该属性  
				 *   
				 * 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件  
				 * 	注意该事件需要通过addEventListener()函数来绑定  
				 */  
  
  
    box1.onmousewheel = function(event){  
  
        event = event || window.event;  
  
  
        //event.wheelDelta 可以获取鼠标滚轮滚动的方向  
        //向上滚 120   向下滚 -120  
        //wheelDelta这个值我们不看大小,只看正负  
  
        //alert(event.wheelDelta);  
  
        //wheelDelta这个属性火狐中不支持  
        //在火狐中使用event.detail来获取滚动的方向  
        //向上滚 -3  向下滚 3  
        //alert(event.detail);  
  
  
       				 /*  
					 * 当鼠标滚轮向下滚动时,box1变长  
					 * 	当滚轮向上滚动时,box1变短  
					 */  
        //判断鼠标滚轮滚动的方向  
        if(event.wheelDelta > 0 || event.detail < 0){  
            //向上滚,box1变短  
            box1.style.height = box1.clientHeight - 10 + "px";  
  
        }else{  
            //向下滚,box1变长  
            box1.style.height = box1.clientHeight + 10 + "px";  
        }  
  
       				 /*  
					 * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false  
					 * 需要使用event来取消默认行为event.preventDefault();  
					 * 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错  
					 */  
       				 event.preventDefault && event.preventDefault();  
  
  
        			/*  
					 * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,  
					 * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为  
					 */  
       				 return false;  
  
  
  
  
    };  
  
    //为火狐绑定滚轮事件  
    bind(box1,"DOMMouseScroll",box1.onmousewheel);  
  
  
};  
  
  
function bind(obj , eventStr , callback){  
    if(obj.addEventListener){  
        //大部分浏览器兼容的方式  
        obj.addEventListener(eventStr , callback , false);  
    }else{  
        /*  
					 * this是谁由调用方式决定  
					 * callback.call(obj)  
					 */  
        //IE8及以下  
        obj.attachEvent("on"+eventStr , function(){  
            //在匿名函数中调用回调函数  
            callback.call(obj);  
        });  
    }  
}  
  
</script>  
</head>  
<body style="height: 2000px;">  
  
    <div id="box1"></div>  
  
</body>  
</html>  
  

image-20230102102622387

57.键盘事件

键盘事件:
onkeydown  按键被按下
对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。
onkeyup  按键被松开

键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document

keyCode
   可以通过keyCode来获取按键的编码
   通过它可以判断哪个按键被按下
除了keyCode,事件对象中还提供了几个属性
altKey
ctrlKey
shiftKey
这个三个用来判断alt ctrl 和 shift是否被按下
如果按下则返回true,否则返回false

//console.log(event.keyCode);  
  
//判断一个y是否被按下  
//判断y和ctrl是否同时被按下  
if(event.keyCode === 89 && event.ctrlKey){  
	console.log("ctrl和y都被按下了");  
}  

input.onkeydown = function(event) {  
    event = event || window.event;  
    //数字 48 - 57  
    //使文本框中不能输入数字  
    if(event.keyCode >= 48 && event.keyCode <= 57) {  
        //在文本框中输入内容,属于onkeydown的默认行为  
        //如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中  
        return false;  
    }  
}; 

练习 键盘移动

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
		    #box1{  
					width: 100px;  
					height: 100px;  
					background-color: red;  
				}  
		    </style>  
		<script type="text/javascript">
			window.onload = function(){ 
				//var box1 = document.getElementById("box1");
				document.onkeydown = function(event){
					event = event || window.event;
					
					//定义一个变量,来表示移动的速度
					var speed = 10;
					//当用户按了3Ctrl后,速度加快
					if(event.ctrlKey){
						speed = 100;
					}
					/* 
						37 向左, 38 向右 ,39 向上, 40向下
					 */
					switch(event.keyCode){
						case 37: 
							//alert("11");
							box1.style.left = box1.offsetLeft-speed+"px";
							break;
						case 38:
							//alert("22");
							box1.style.left = box1.offsetLeft + speed + "px";
							break;
						case 39:
							//alert("33");
							box1.style.top = box1.offsetTop - speed + "px";
							break;
						case 40:
							//alert("44");
							box1.style.top = box1.offsetTop + speed + "px";
							break;			
					}
				}
				
				
			}
		</script>	
	</head>
	<body>
		 <div id="box1"></div> 
	</body>
</html>

58.BOM

浏览器对象模型(browser object model)
BOM可以使我们通过JS来操作浏览器
在BOM中为我们提供了一组对象,用来完成对浏览器的操作
BOM对象
	Window
	   代表的是整个浏览器的窗口,同时window也是网页中的全局对象
	Navigator
	   代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
	Location
	   代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
	History
       代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
		由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
		而且该操作只在当次访问时有效
	Screen
       代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息

这些BOM对象在浏览器中都是作为window对象的属性保存的,
可以通过window对象来使用,也可以直接使用

1.Navigator

代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息,
userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,
不同的浏览器会有不同的userAgent

火狐的userAgent
Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0

Chrome的userAgent
Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36

IE8
Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE9
Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE10
Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE11
Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了

alert(navigator.appName);  
  
var ua = navigator.userAgent;  
  
console.log(ua);  
  
if(firefoxi.test(ua)){  
	alert("你是火狐!!!");  
}else if(chromei.test(ua)){  
	alert("你是Chrome");  
}else if(msiei.test(ua)){  
	alert("你是IE浏览器~~~");  
}else if("ActiveXObject" in window){  
	alert("你是IE11,枪毙了你~~~");  
}  
//如果通过userAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息
// 比如ActiveXObject

image-20230102113853107

2.History

History
  - 对象可以用来操作浏览器向前或向后翻页
length
	属性,可以获取到当成访问的链接数量
back()
	可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward()
	可以跳转下一个页面,作用和浏览器的前进按钮一样
go()
    可以用来跳转到指定的页面
    它需要一个整数作为参数
    1:表示向前跳转一个页面 相当于forward()
    2:表示向前跳转两个页面
    	-1:表示向后跳转一个页面
    	-2:表示向后跳转两个页面
        
	history.length;
	history.back();
	history.forward();
	history.go(1);        

3.Location

Location
   该对象中封装了浏览器的地址栏的信息
如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
alert(location);
如果直接将location属性修改为一个完整的路径,或相对路径
则我们页面会自动跳转到该路径,并且会生成相应的历史记录
location = "http:www.baidu.com";
location = "01.BOM.html";

assign()
   用来跳转到其他的页面,作用和直接修改location一样
reload()
   用于重新加载当前页面,作用和刷新按钮一样
   如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面
   location.reload(true);
replace()
    可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
    不会生成历史记录,不能使用回退按钮回退

image-20230102113838672

59.window 的一些方法

image-20230102114420395

60.定时器简介

setInterval()
 定时调用
 可以将一个函数,每隔一段时间执行一次
    参数:
        1.回调函数,该函数会每隔一段时间被调用一次
        2.每次调用间隔的时间,单位是毫秒

    返回值:
    返回一个Number类型的数据
    这个数字用来作为定时器的唯一标识
clearInterval()可以用来关闭一个定时器
	方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器

clearInterval()可以接收任意参数,
    如果参数是一个有效的定时器的标识,则停止对应的定时器
    如果参数不是一个有效的标识,则什么也不做

var num = 1;  
var timer = setInterval(function() {  
	count.innerHTML = num++;  
	if(num == 11) {  
		//关闭定时器  
		clearInterval(timer);  
	}  
}, 1000);  

定时器练习(自动切换图片)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			img{
				width: 400px;
				hyphens:350px;;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				//使图片自动切换
				var img1 = document.getElementById("img1");
				//创建一个数组来保存图片的路径
				var imgArr = ["img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg"];
				var index = 0;
				
				//定义一个变量用来保存定时器的标识
				var timer;
				//为btn01绑定一个单击响应函数
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					/* 
						目前,我们每点击一次按钮,就会开启一个定时器,
							点击多次就会开启多个定时器,这就导致图片的切换速度过快
							并且我们只能关闭最后一次开启的定时器
					 */
					//开启定时器之前,需要将当前元素上上的其他定时器关闭
					clearInterval(timer);
					
					//开启一个定时器,来自动切换图片
				 timer = setInterval(function(){
						//使索引自增
						index++;
						//判断索引是否超过最大索引
						if(index >= imgArr.length){
							index = 0;
						}
						//或者
						//index = index % imgArr.length;
							//修改img1的src属性
							img1.src = imgArr[index];
						
					},1000);
				}
				
				var btn02 = document.getElementById("btn02");
				btn02.onclick  =function(){
					/* 
						clearInterval()可以接收任意参数,
							如果参数是一个有效的定时器的标识,则停止对应的定时器
							如果参数不是一个有效的标识,则什么也不做
					 */
					clearInterval(timer);
				}
			}
			
		</script>
	</head>
	<body>
		<img id="img1" src="img/1.jpg" ><br>
		<button id="btn01" type="button">开始</button>
		<button id="btn02" type="button">停止</button>
	</body>
</html>

61.延时调用

setTimeout

延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择

var timer = setTimeout(function(){
console.log(num++);
},3000);

使用clearTimeout()来关闭一个延时调用
clearTimeout(timer);

练习(点击按钮以后box1向右 向上 向左 向下 移动)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			#box1{
				width: 100px;
				height: 100px;
				background-color: red;
				position: absolute;
				left: 0;
			}
			#box2{
				width: 100px;
				height: 100px;
				background-color: yellow;
				position: absolute;
				left: 0;
				top: 200px;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				var box1 = document.getElementById("box1");
				var btn01 = document.getElementById("btn01");
				var btn02 = document.getElementById("btn02");
				var btn03 = document.getElementById("btn03");
				var btn04 = document.getElementById("btn04");
				//点击按钮后,使box1向右移动(left值增大)
				btn01.onclick = function(){
					move(box1,"left",800,10);
				}
				btn02.onclick = function(){
					move(box1,"left",0,10);
				}
				btn03.onclick = function(){
					move(box2,"left",800,10);
				}
				btn04.onclick = function(){
					move(box2,"top",800,10); //向下移动
					//move(box2,"width",800,10); //宽度增加
					//move(box2,"height",800,10);	
					move(box2,"width",800,10,function(){  //先变宽,再变高
						//alert("动画执行完毕了")
						move(box2,"height",800,10,function(){
							
						})
					});
					
				}
			
				var timer;
				/* 
					尝试创建一个可用执行简单动画的函数
					参数:
						obj:要执行动画的对象
						attr: 要执行动画的样式,比如 left  top width height
						target:执行动画的目标位置
						speed:移动的速度(整数向右移,负数向左移)
						callback:回调函数,这个函数将会在动画执行完毕以后执行
				 */
				function move(obj,attr,target,speed,callback){
					//关闭上一个定时器
					clearInterval(obj.timer);
					
					//获取元素目前的位置
					var current =parseInt(getStyle(obj,attr));
					//判断速度的正负值
					//如果从0向800移动,则speed为正
					//如果从800向0移动,则speed为负
					if(current > target){
						//此时速度应为负值
						speed = -speed;
					}
					
					
					//box1.style.left = "300px";
					//开启一个定时器,用来执行动画效果
					//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
					 obj.timer = setInterval(function(){
						//获取box1的原来的left值
						var oldvalue =parseInt(getStyle(obj,attr));
						//在旧值的基础上增加 
						var newValue = oldvalue + speed;
						
						//判断newValue是否大于800
						//向左移动时,需要判断newvalue是否小于target
						//向右移动时,需要判断newvalue是否大于target
						if(speed < 0 && newValue < target || speed > 0 && newValue > target){
							newValue = target;
						}
						
						//将新值设置给box1
						obj.style[attr] = newValue + "px";
						//alert(oldvalue);
						
						//当元素移动到800px时,使其停止执行动画
						if(newValue == target){
							//达到目标,关闭定时器
							clearInterval(obj.timer);
							//动画执行完毕,调用回调函数
							//以下语句是 用来判断 如果有回调函数则执行,没有则不执行
							callback && callback();
						}
						
					},30);
				}
				
				
				/*
					定义一个函数,用来获取指定元素的当前的样式
					参数;
						obj 要获取样式的元素
						name  要获取的样式名
				 */
				function getStyle(obj,name){
					if(window.getComputedStyle){
						//正常浏览器的方式 , 具有getComputedStyle()方法
						return getComputedStyle(obj,null)[name];
					}else{
						//IE8的方式 ,没有getComputedStyle()方法
						return obj.currentStyle[name];
					}
				};
			}
			
		</script>
	</head>
	<body>
		<button type="button" id="btn01">点击按钮以后box1向右移动</button>
		<button type="button" id="btn02">点击按钮以后box1向左移动</button>
		<button type="button" id="btn03">点击按钮以后box2向右移动</button>
		<button type="button" id="btn04">点击按钮以后box2向下移动</button>
		<div id="box1"></div>
		<div id="box2"></div>
		<div id="" style="width: 0;height: 1000px;border: 1px black solid;left: 800px;top: 0; position: absolute;" >
			
		</div>
	</body>
</html>

示例:

image-20230102145853772

62.类的操作

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			.b1{
				width: 100px;
				height: 100px;
				background-color: red;
			}
			.b2{
				width: 200px;
				/* height: 200px; */
				background-color: yellow;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				var btn01 = document.getElementById("btn01");
				var box = document.getElementById("box");
				btn01.onclick = function(){
					//修改box的class属性
					/* 
						我们可以通过修改元素的class属性来间接的修改样式
						这样一来,我们只需要修改一次,即可同时修改多个样式,
						  浏览器只需要重新渲染页面一次,性能比较好
						  并且这种方式,可以使表现和行为进一步的分离
					*/
					//box.className="b2";
					//box.className +=" b2"; //这样写的话 既有b1的样式,又有b2的样式
					//addClass(box,"b2");
					//alert(hasClass(box,"b2"));
					//removeClass(box,"b2")
					toggleClass(box,"b2");
				}
				
				//定义一个函数,用来向一个元素中添加指定的class属性值
				/* 
					参数:
						obj 要添加class属性的元素
						cn  要添加的class值
				 */
				function addClass(obj,cn){
					//检查obj中是否含有cn
					if(!hasClass(obj,cn)){
						obj.className += " "+cn;
					}
				}
				
				/* 
					判断一个元素中是否含有指定的class属性值
					  如果有该class,则返回true,没有则返回false
				 */
				function hasClass(obj,cn){
					//判断obj中有没有cn  class
					//创建一个正则表达式
					//var reg = /\bb2\b/;
					var reg = new RegExp("\\b"+cn+"\\b");
					//alert(reg);
					return reg.test(obj.className);
				}
				
				/* 
					删除一个元素中的指定的class属性
				 */
				function removeClass(obj,cn){
					//创建一个正则表达式
					var reg = new RegExp("\\b"+cn+"\\b");
					
					//删除class
					obj.className = obj.className.replace(reg,"");
				}
				/*
					toggleClass可以用来切换一个类
					 如果元素中具有该类,则删除
					 如果元素中没有该类,则添加
				 */
				function toggleClass(obj,cn){
					//判断obj中是否含有cn 
					if(hasClass(obj,cn)){
						//有,则删除
						removeClass(obj,cn);
					}else{
						//没有,则添加
						addClass(obj,cn);
					}
				}
				
			}
			
		</script>
	</head>
	<body>
		<button type="button" id="btn01">点击按钮以后修改box样式</button>
		<br><br />
		<div class="b1" id="box"></div>
	</body>
</html>

image-20230102184229468

63.JSON

JSON就是一个特殊格式的字符串,只不过JSON字符串的属性名必须加双引号

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			/* 
				JSON
				   - JS中的对象只有JS自己认识,其他的语言都不认识
				   - JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别
						并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
				   - JSON
						- JavaScript Object Notation JS对象表示法
						- JSON和JS对象的格式一样,只不过JSON字符串的属性名必须加双引号   
							其他和JS语法一致
					   JSON分类:
							1.对象 {}
							2.数组 []	 
						
						JSON中允许的值:
							  1.字符串
							  2.数值
							  3.布尔值
							  4.null
							  5.对象
							  6.数组
			 */
			//创建一个对象
			var obj1 = {name:"孙悟空",age:18,gender:"男"};
			console.log(obj1);
			console.log(typeof obj1); //object
			
			//json格式
			var obj = '{"name":"孙悟空","age":18,"gender":"男"}';
			var arr = '[1,2,3,"hello",true]';
			var obj2 = '{"arr":[1,2,3]}';
			console.log(obj);
			console.log(typeof obj); //string
			
			//console.log(JSON);  //[object JSON]
			/* 
				将JSON字符串转换为JS中的对象
				 在JS中,为我们提供了一个工具类,就叫JSON
				 这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
			 */
			var json = '{"name":"孙悟空","age":18,"gender":"男"}';
			/* 
				json -->js对象
				  JSON.parse()
						- 可以将以JSON字符串转换为js对象
						- 它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
			 */
			var o = JSON.parse(json);
			var o2 = JSON.parse(arr);
			console.log(o.name);
			console.log(o2[3]); //hello
			
			
			/* 
				JS对象 ---> JSON
				  JSON.stringify()
				       - 可以将一个JS对象转换为JSON字符串
					   - 需要一个js对象作为参数,会返回一个JSON字符串
			 */
			var obj4 = {name:"孙悟空",age:18,gender:"男"};
			var str = JSON.stringify(obj4);
			console.log(str);
			
			//JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错
			
		</script>
	</head>
	<body>
	</body>
</html>

其他的一个方法(IE7以下支持)

	<script type="text/javascript">
			var obj = '{"name":"孙悟空","age":18,"gender":"男"}';
			/* 
				eval()
				  - 这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
				  - 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块
					   如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
					   
				  - eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,
					   但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患	   
			 */
			var obj = eval("("+obj + ")");  //{name: '孙悟空', age: 18, gender: '男'}
			console.log(obj);
			
		</script>

64.总结DOM常用的方法

getElementById()    返回带有指定ID 的元素。
getElementsByTagName()  返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByClassName()   返回包含带有指定类名的所有元素的节点列表。
getElementsByName('a') 通过name属性获取一组元素节点对象
document.querySelector('#a') 通过CSS选择器来获取一个元素节点对象
document.querySelectorAll('span') 通过CSS选择器来获取一组元素节点对象
appendChild()   把新的子节点添加到指定节点。
removeChild()   删除子节点。
replaceChild()  替换子节点。
insertBefore()  在指定的子节点前面插入新的子节点。
createAttribute()   创建属性节点。
createElement() 创建元素节点。
createTextNode()    创建文本节点。
getAttribute()  返回指定的属性值。
setAttribute()  把指定属性设置或修改为指定的值。
当前节点.paretNode   表示当前节点的父节点
当前节点.previousSibling 表示当前节点的前一个兄弟节点
当前节点.nextSibling 表示当前节点的后一个兄弟节点
父节点.firstchild 可以获取第一个子节点(包括空白文本节点)
父节点.firstElementchild 可以获取第一个子元素(不包括空白文本节点)
父节点.childNodes 表示当前节点的所有子节点

65.一些实用性很高的网站

花生壳内网穿透: https://www.oray.com/
JQ所有版本: https://www.jq22.com/jquery-info122
站长素材: https://sc.chinaz.com/
懒人之家: https://www.lanrenzhijia.com/
jQuery之家: http://www.htmleaf.com/
17素材库: https://www.17sucai.com/
jQuery插件库: https://www.jq22.com/

正则表达式大全: http://c.runoob.com/front-end/854

natapp内网穿透: https://natapp.cn/
jQuery文档: http://caibaojian.com/jquery/
node.js入门教程: http://nodejs.cn/learn
node.js中文文档: http://nodejs.cn/api/assert.html#assert_assert
swiper: https://www.swiper.com.cn/demo/index.html
bootstrap中文文档: https://v3.bootcss.com/
axios中文文档: http://www.axios-js.com/zh-cn/docs/
站长工具: http://tool.chinaz.com/
和风天气接口: https://dev.qweather.com/docs/api/weather/
electron文档: https://www.electronjs.org/docs
百度地图接口: http://lbsyun.baidu.com/index.php?title=首页
MD5加密: https://crypot.51strive.com/
puppeteer.js中文文档: http://www.puppeteerjs.com/#?product=Puppeteer&version=v2.0.0&show=api-class-puppeteer
MySQL: https://dev.mysql.com/downloads/installer/

posted @ 2023-01-02 20:05  爲誰心殇  阅读(140)  评论(0编辑  收藏  举报
>