JavaScript 基础
JavaScript概述
JavaScript的历史
- 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言)
- Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本语言.Sun和Netscape共同完成.后改名叫Javascript
- 微软随后模仿在其IE3.0的产品中搭载了一个JavaScript的克隆版叫Jscript.
- 为了统一三家,ECMA(欧洲计算机制造协会)定义了ECMA-262规范.国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 作为标准(ISO/IEC-16262)。从此,Web 浏览器就开始努力(虽然有着不同的程度的成功和失败)将 ECMAScript 作为 JavaScript 实现的基础。EcmaScript是规范.
ECMAScript
尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
- 核心(ECMAScript)
- 文档对象模型(DOM) Document object model (整合js,css,html)
- 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)
- Javascript 在开发中绝大多数情况是基于对象的.也是面向对象的.
简单地说,ECMAScript 描述了以下内容:
- 语法
- 类型
- 语句
- 关键字
- 保留字
- 运算符
- 对象 (封装 继承 多态) 基于对象的语言.使用对象.
JavaScript的引入方式
1
2
3
4
5
6
|
{ #1 直接编写#} <script> alert( 'hello yuan' ) < / script> { #2 导入文件#} <script src = "hello.js" >< / script> |
二 JavaScript的基础
1.let 特点: 1.局部作用域 2.不会存在变量提升 3.变量不能重复声明 2.const 特点: 1.局部作用域 2.不会存在变量提升 3.不能重复声明,只声明常量 不可变的量 3.模板字符串 tab键上面的反引号 ${变量名}来插值 let name = '未来'; let str = `我是${name}` 4.箭头函数 let funcname = ()=>{} this的指向发生了改变 // let add2 = (x)=>{ // return x // } // 简写如下 // let add2 = x => x; // console.log(add2(30)) let person = { name: "日天", age: 30, fav: function () { console.log(this); //this指向 当前的对象 console.log(this.name); } } /* let person2 = { name: "日天2", age: 30, fav: () => { console.log(this); //this指向 发生了改变。this指向 定义person2的父级对象(上下文) console.log(this.name); } } person2.fav() */ // 对象的单体模式 let person3 = { name:'日天', fav(){ console.log(this); } // fav:function () { // // } } person3.fav(); 5.es6的类 原型 prototype 当前类的父类(继承性) class Person{ constructor(name){ this.name = name; } fav(){ } } /* function Vue(name,age) { this.name = name; this.age = age; } // 基于原型给对象声明方法 Vue.prototype.showName = function () { console.log(this.name); } var p1 = new Person('alex','29'); */ class Person{ constructor(name='alex',age=18){ this.name = name; this.age = age; } showname(){ console.log(this.name); } showage(){ } } let V = new Person(); V.showname();
2.1 变量
x=5 y=6 z=x+y
在代数中,我们使用字母(比如 x)来保存值(比如 5)。
通过上面的表达式 z=x+y,我们能够计算出 z 的值为 11。
在 JavaScript 中,这些字母被称为变量。
0 变量是弱类型的(很随便);
1 声明变量时不用声明变量类型. 全都使用var关键字;
1
|
var a; |
2 一行可以声明多个变量.并且可以是不同类型.
1
|
var name = "yuan" , age = 20 , job = "lecturer" ; |
3 (了解) 声明变量时 可以不用var. 如果不用var 那么它是全局变量.
4 变量命名,首字符只能是字母,下划线,$美元符 三选一,且区分大小写,x与X是两个变量
5 变量还应遵守以下某条著名的命名规则:
Camel 标记法 首字母是小写的,接下来的字母都以大写字符开头。例如: var myTestValue = 0, mySecondValue = "hi"; Pascal 标记法 首字母是大写的,接下来的字母都以大写字符开头。例如: Var MyTestValue = 0, MySecondValue = "hi"; 匈牙利类型标记法 在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,如下所示“ Var iMyTestValue = 0, sMySecondValue = "hi";
注意:
1 function func1(){ 2 3 var a = 123; 4 b=456 5 } 6 7 func1(); 8 9 // alert(a); 10 // alert(b); 11 // 不推荐
2.2 基础规范
1 每行结束可以不加分号. 没有分号会以换行符作为每行的结束
1 a=1;b=2; 2 a=1 b=2;------错误 3 4 a=1 5 b=2 6 7 //推荐 8 a=1; 9 b=2; 10 11 { 12 a=1; 13 b=2; 14 //推荐加tab 15 a=1; 16 b=2; 17 }
2 注释 支持多行注释和单行注释. /* */ //
3 使用{}来封装代码块
2.3 常量和标识符
常量 :直接在程序中出现的数据值
标识符:
- 由不以数字开头的字母、数字、下划线(_)、美元符号($)组成
- 常用于表示函数、变量等的名称
- 例如:_abc,$abc,abc,abc123是标识符,而1abc不是
- JavaScript语言中代表特定含义的词称为保留字,不允许程序再定义为标识符
2.4 数据类型
数字类型(Number)
简介 最基本的数据类型 不区分整型数值和浮点型数值 所有数字都采用64位浮点格式存储,相当于Java和C语言中的double格式 能表示的最大值是±1.7976931348623157 x 10308 能表示的最小值是±5 x 10 -324
整数:
在JavaScript中10进制的整数由数字的序列组成
精确表达的范围是
-9007199254740992 (-253) 到 9007199254740992 (253)
超出范围的整数,精确度将受影响
浮点数:
使用小数点记录数据
例如:3.4,5.6
使用指数记录数据
例如:4.3e23 = 4.3 x 1023
16进制和8进制数的表达
16进制数据前面加上0x,八进制前面加0
16进制数是由0-9,A-F等16个字符组成
8进制数由0-7等8个数字组成
16进制和8进制与2进制的换算
# 2进制: 1111 0011 1101 0100 <-----> 16进制:0xF3D4 <-----> 10进制:62420 # 2进制: 1 111 001 111 010 100 <-----> 8进制:0171724
字符串(String)
简介 是由Unicode字符、数字、标点符号组成的序列 字符串常量首尾由单引号或双引号括起 JavaScript中没有字符类型 常用特殊字符在字符串中的表达 字符串中部分特殊字符必须加上右划线\ 常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 9 <script> 10 11 /* 12 13 2003年3月20日,伊拉克战争爆发,以美军为主的联合部队仅用20多天就击溃了萨达姆的军队。这是继十多年前的海湾战争后,美军又一次取得的大规模压倒性军事胜利 14 15 */ 16 17 18 var name = '伊拉克'; 19 var am = '美军'; 20 // 字符串拼接 21 // var str = "2003年3月20日,"+name+"战争爆发,以美军为主的联合部队仅用20多天就击溃了萨达姆的军队。这是继十多年前的海湾战争后,"+am+"又一次取得的大规模压倒性军事胜利。"; 22 // var str = "2003年3月20日,"+name+"战争爆发,以美军为主的联合部队仅用20多天就击溃了萨达姆的军队。这是继十多年前的海湾战争后,美军又一次取得的大规模压倒性军事胜利"; 23 24 // ***** es6的模块字符串 tab键上面的反引号 `` 添加变量使用${变量名}***** 25 var str = `2003年3月20日,${name}战争爆发,以${am}为主的联合部队仅用20多天就击溃了萨达姆的军队。这是继十多年前的海湾战争后,美军又一次取得的大规模压倒性军事胜利。`; 26 27 console.log(str); 28 29 var a1 = '1'; 30 var a2 = '2'; 31 console.log(a1-a2); 32 var b1 = 'one'; 33 var b2 = 'two'; 34 35 console.log(b1*b2); //NaN not a number 36 37 console.log(typeof(b1*b2)); //number 38 39 40 </script> 41 </body> 42 </html>
String数据类型的使用
- 特殊字符的使用方法和效果
- Unicode的插入方法
1
2
3
4
|
<script> var str = "\u4f60\u597d\n欢迎来到\"JavaScript世界\"" ; alert( str ); < / script> |
布尔型(Boolean)
简介 Boolean类型仅有两个值:true和false,也代表1和0,实际运算中true=1,false=0 布尔值也可以看作on/off、yes/no、1/0对应true/false Boolean值主要用于JavaScript的控制语句,例如 if (x==1){ y=y+1; }else { y=y-1; }
Null & Undefined
Undefined 类型
Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。
当函数无明确返回值时,返回的也是值 "undefined";
Null 类型
另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。
尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。
var person=new Person()
var person=null
数据类型转换
JavaScript属于松散类型的程序语言 变量在声明的时候并不需要指定数据类型 变量只有在赋值的时候才会确定数据类型 表达式中包含不同类型数据则在计算过程中会强制进行类别转换
数字 + 字符串:数字转换为字符串
数字 + 布尔值:true转换为1,false转换为0
字符串 + 布尔值:布尔值转换为字符串true或false
强制类型转换函数
函数parseInt: 强制转换成整数 例如parseInt("6.12")=6 ; parseInt(“12a")=12 ; parseInt(“a12")=NaN ;parseInt(“1a2")=1 函数parseFloat: 强制转换成浮点数 parseFloat("6.12")=6.12 函数eval: 将字符串强制转换为表达式并返回结果 eval("1+1")=2 ; eval("1<2")=true
类型查询函数(typeof)
ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。
函数typeof :查询数值当前类型 (string / number / boolean / object )
例如typeof("test"+3) "string" 例如typeof(null) "object " 例如typeof(true+1) "number" 例如typeof(true-false) "number"
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <script> 9 10 //使用Object()内置的构造函数来创建对象 11 12 13 // new Array() 14 // [] 15 16 /* 17 var person = new Object(); 18 19 person.name = 'alex'; 20 21 person.age = 18; 22 23 person.fav = function() { 24 25 alert(this.name); 26 } 27 person.fav(); 28 */ 29 /* 30 // 字面量方式创建对象 31 var person = { 32 name:'玖妖', 33 age:18, 34 fav:function() { 35 alert(this.name) 36 } 37 }; 38 39 person.fav(); 40 */ 41 42 43 function createPerson(){ 44 var person = new Object(); 45 person.name = 'alex'; 46 47 person.age = 18; 48 49 person.fav = function() { 50 51 alert(this.name); 52 } 53 return person; 54 } 55 function createFruit(){ 56 var fruit = new Object(); 57 fruit.name = 'alex'; 58 59 fruit.age = 18; 60 61 fruit.fav = function() { 62 63 alert(this.name); 64 } 65 return fruit; 66 } 67 var p1 = createPerson(); 68 var f1 = createFruit(); 69 70 console.log(p1 instanceof Object); 71 console.log(f1 instanceof Object); 72 </script> 73 </body> 74 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <script> 9 // var arr = new Array(); 10 // console.log(arr); 11 //自定义构造函数 12 function Person(name,age) { 13 14 this.name = name; 15 this.age = age; 16 this.fav = function() { 17 alert(this.name); 18 } 19 } 20 21 function Fruit(name,age) { 22 23 this.name = name; 24 this.age = age; 25 this.fav = function() { 26 alert(this.name); 27 } 28 } 29 var p1 = new Person('alex',17); 30 var f1 = new Fruit('wusir',19); 31 console.log(p1 instanceof Object); 32 console.log(f1 instanceof Object); 33 console.log(p1 instanceof Person); 34 console.log(f1 instanceof Fruit); 35 36 </script> 37 38 </body> 39 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 9 <script> 10 function Person(name,age) { 11 this.name = name; 12 this.age = age; 13 } 14 // Person.prototype 它是person的父类 15 16 17 // 原型 prototype 18 Person.prototype.showName = function() { 19 // this指的是person 20 console.log(this.name) 21 } 22 var p1 = new Person('alex',18); 23 console.log(p1); 24 p1.showName(); 25 </script> 26 27 </body> 28 </html>
ECMAScript 运算符
ECMAScript 算数运算符
加(+)、 减(-)、 乘(*) 、除(/) 、余数(% ) 加、减、乘、除、余数和数学中的运算方法一样 例如:9/2=4.5,4*5=20,9%2=1
-除了可以表示减号还可以表示负号 例如:x=-y
+除了可以表示加法运算还可以用于字符串的连接 例如:"abc"+"def"="abcdef"
递增(++) 、递减(--)
假如x=2,那么x++表达式执行后的值为3,x--表达式执行后的值为1
i++相当于i=i+1,i--相当于i=i-1
递增和递减运算符可以放在变量前也可以放在变量后:--i
var i=1;
console.log(i++);
console.log(++i);
console.log(i--);
console.log(--i);
一元加减法:
var a=1;
var b=1;
a=-a; //a=-1
var c="10";
alert(typeof (c));
c=+c; //类型转换
alert(typeof (c));
// -------------------
var d="yuan";
d=+d;
alert(d);//NaN:属于Number类型的一个特殊值,当遇到将字符串转成数字无效时,就会得到一个NaN数据
alert(typeof(d));//Number
//NaN特点:
var n=NaN;
alert(n>3);
alert(n<3);
alert(n==3);
alert(n==NaN);
alert(n!=NaN);//NaN参与的所有的运算都是false,除了!=
ECMAScript 逻辑运算符
等于 ( == ) 、不等于( != ) 、 大于( > ) 、 小于( < ) 大于等于(>=) 、小于等于(<=) 与 (&&) 、或(||) 、非(!)
1 && 1 = 1 1 || 1 = 1
1 && 0 = 0 1 || 0 = 1
0 && 0 = 0 0 || 0 = 0
!0=1
!1=0
逻辑 AND 运算符(&&)
逻辑 AND 运算的运算数可以是任何类型的,不止是 Boolean 值。
如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:
- 如果某个运算数是 null,返回 null。
- 如果某个运算数是 NaN,返回 NaN。
- 如果某个运算数是 undefined,返回undefined。
逻辑 OR 运算符(||)
与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值
ECMAScript 赋值运算符
赋值 = JavaScript中=代表赋值,两个等号==表示判断是否相等 例如,x=1表示给x赋值为1 if (x==1){...}程序表示当x与1相等时 if(x==“on”){…}程序表示当x与“on”相等时 配合其他运算符形成的简化表达式 例如i+=1相当于i=i+1,x&=y相当于x=x&y
实例:
1 == “2” 2 === “2” 3 != “4” 4 !== “4” 5 6 var a = 2; var b = 4; 7 var c = a<b | --b>--a; 8 var c = a<b || --b>--a; 9 var c = a<b &&--b>--a; 10 var c = a<b & --b>--a;
ECMAScript等性运算符
执行类型转换的规则如下:
- 如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
- 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
- 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
- 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
- 值 null 和 undefined 相等。
- 在检查相等性时,不能把 null 和 undefined 转换成其他值。
- 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
- 如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
ECMAScript 关系运算符(重要)
1
2
|
var bResult = "Blue" < "alpha" ; alert(bResult); //输出 true |
在上面的例子中,字符串 "Blue" 小于 "alpha",因为字母 B 的字符代码是 66,字母 a 的字符代码是 97。
比较数字和字符串
另一种棘手的状况发生在比较两个字符串形式的数字时,比如:
1
2
|
var bResult = "25" < "3" ; alert(bResult); //输出 "true" |
上面这段代码比较的是字符串 "25" 和 "3"。两个运算数都是字符串,所以比较的是它们的字符代码("2" 的字符代码是 50,"3" 的字符代码是 51)。
不过,如果把某个运算数该为数字,那么结果就有趣了:
1
2
|
var bResult = "25" < 3; alert(bResult); //输出 "false" |
这里,字符串 "25" 将被转换成数字 25,然后与数字 3 进行比较,结果不出所料。
总结:
1
2
|
比较运算符两侧如果一个是数字类型,一个是其他类型,会将其类型转换成数字类型. 比较运算符两侧如果都是字符串类型,比较的是最高位的asc码,如果最高位相等,继续取第二位比较. |
Boolean运算符(重要)
var temp=new Object();// false;[];0; null; undefined;object(new Object();) if(temp){ console.log("yuan") }else { console.log("alex") }
全等号和非全等号
等号和非等号的同类运算符是全等号和非全等号。这两个运算符所做的与等号和非等号相同,只是它们在检查相等性前,不执行类型转换。
控制语句
if 控制语句
if-else基本格式 if (表达式){ 语句1; ...... }else{ 语句2; ..... } 功能说明 如果表达式的值为true则执行语句1, 否则执行语句2
var x= (new Date()).getDay(); //获取今天的星期值,0为星期天 var y; if ( (x==6) || (x==0) ) { y="周末"; }else{ y="工作日"; } alert(y); //等价于 y="工作日"; if ( (x==6) || (x==0) ) { y="周末"; }
if 可以单独使用
if语句嵌套格式 if (表达式1) { 语句1; }else if (表达式2){ 语句2; }else if (表达式3){ 语句3; } else{ 语句4; }
1 if (x==1){ 2 y="星期一"; 3 }else if (x==2){ 4 y="星期二"; 5 ... 6 }else if (x==6){ 7 y="星期六"; 8 }else if (x==0){ 9 y="星期日"; 10 }else{ 11 y="未定义";
switch 选择控制语句
switch基本格式 switch (表达式) { case 值1:语句1;break; case 值2:语句2;break; case 值3:语句3;break; default:语句4; }
switch(x){ case 1:y="星期一"; break; case 2:y="星期二"; break; case 3:y="星期三"; break; case 4:y="星期四"; break; case 5:y="星期五"; break; case 6:y="星期六"; break; case 7:y="星期日"; break; default: y="未定义";
}
switch比else if结构更加简洁清晰,使程序可读性更强,效率更高。
1 首先要看一个问题,if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断;而 switch 只能对基本类型进行数值比较。两者的可比性就仅限在两个基本类型比较的范围内。 2 说到基本类型的数值比较,那当然要有两个数。然后重点来了—— 3 if 语句每一句都是独立的,看下面的语句: 4 if (a == 1) ... 5 else if (a == 2) ... 6 这样 a 要被读入寄存器两次,1 和 2 分别被读入寄存器一次。于是你是否发现其实 a 读两次是有点多余的,在你全部比较完之前只需要一次读入寄存器就行了,其余都是额外开销。但是 if 语句必须每次都把里面的两个数从内存拿出来读到寄存器,它不知道你其实比较的是同一个 a。 7 于是 switch case 就出来了,把上面的改成 switch case 版本: 8 switch (a) { 9 case 0: 10 break; 11 case 1: 12 } 13 14 总结: 15 16 1.switch用来根据一个整型值进行多路分支,并且编译器可以对多路分支进行优化 17 2.switch-case只将表达式计算一次,然后将表达式的值与每个case的值比较,进而选 18 择执行哪一个case的语句块 19 3.if..else 的判断条件范围较广,每条语句基本上独立的,每次判断时都要条件加载 20 一次。 21 所以在多路分支时用switch比if..else if .. else结构要效率高。
for 循环控制语句
for循环基本格式 for (初始化;条件;增量){ 语句1; ... } 功能说明 实现条件循环,当条件成立时,执行语句1,否则跳出循环体
for (var i=1;i<=7;i++){ document.write("<H"+i+">hello</H "+i+"> "); document.write("<br>"); } ---------------------------------------------- var arr=[1,"hello",true]//var dic={"1":"111"} for (var i in arr){ console.log(i) console.log(arr[i]) }
Array 类型为每个数组定义了 forEach() 原型方法,使用该方法可以为数组执行迭代操作。具体说明如下: array.forEach(callbackfn[, thisArg]); 参数说明如下: array:一个数组对象。 callbackfn:必需参数,最多可以接收三个参数的函数。forEach 将为数组中的每个元素调用 callbackfn 函数一次。 thisArg:可选参数,callbackfn 函数中的 this 可引用的对象。如果省略 thisArg,则 this 的值为 undefined。 对于数组中出现的每个元素,forEach 方法都会调用 callbackfn 函数一次,采用升序索引顺序,但不会为数组中空元素调用回调函数。 除了数组对象之外,forEach 方法还可以用于有 length 属性且具有已按数字编制索引的属性名的任何对象,如关联数组对象、Arguments 等。 回调函数语法如下: funtion callbackfn(value, index, array); 最多可以使用三个参数来声明回调函数。回调函数的参数说明如下。 value:数组元素的值。 index:数组元素的数字索引。 array:包含该元素的数组对象。 forEach 方法不直接修改原始数组,但回调函数可能会修改它。在 forEach 方法启动后修改数组对象所获得的结果如表所示。 回调函数修改数组的影响 forEach 方法启动后的条件 元素是否传递给回调函数 在数组的原始长度之外添加元素 否 添加元素以填充数组中缺少的元素 是,如果该索引尚未传递给回调函数 元素已更改 是,如果该元素尚未传递给回调函数 从数组中删除元素 否,除非该元素已传递给回调函数 示例1 下面示例使用 forEach 迭代数组 a,然后把每个元素的值和下标索引输出显示,代码如下: function f(value,index,array) { console.log("a[" + index + "] = " + value); } var a = ['a', 'b', 'c']; a.forEach(f); 示例2 下面示例使用 forEach 迭代数组 a,然后计算数组元素的和并输出。 var a = [10, 11, 12], sum = 0; a.forEach (function (value) { sum += value; }); console.log(sum); //返回33 示例3 下面示例演示如何使用 forEach() 方法的第二个参数,该参数为回调函数的 this 传递对象。当迭代数组过程中,先读取数组元素的值,然后改写它的值。 var obj = { f1 : function(value,index,array) { console.log("a[" + index + "] = " + value); arrar[index] = this.f2(value); }, f2 : function (x) {return x * x;} }; var a = [12, 26, 36]; a.forEach(obj.f1, obj); console.log(a); //返回[144, 676, 1296
注意:
1 doms=document.getElementsByTagName("p"); 2 3 for (var i in doms){ 4 console.log(i); // 0 1 2 length item namedItem 5 //console.log(doms[i]) 6 } 7 8 //循环的是你获取的th一个DOM元素集,for in用来循环对象的所有属性,dom元素集包含了你上面输出的属性。 9 //如果你只要循环dom对象的话,可以用for循环: 10 11 for (var i=0;i<doms.length;i++){ 12 console.log(i) ; // 0 1 2 13 //console.log(doms[i]) 14 }
结论:for i in 不推荐使用.
while 循环控制语句
while循环基本格式 while (条件){ 语句1; ... } 功能说明 运行功能和for类似,当条件成立循环执行语句花括号{}内的语句,否则跳出循环
var i=1; while (i<=7) { document.write("<H"+i+">hello</H "+i+"> "); document.write("<br>"); i++; } //循环输出H1到H7的字体大小
1 <script language="JavaScript"> 2 /* sayhello是定义的函数名,前面必须加上function和空格*/ 3 function sayHello(){ 4 var hellostr; 5 var myname=prompt("请问您贵姓?","苑"); 6 hellostr="您好,"+myname+'先生,欢迎进入"探索之旅"!'; 7 alert(hellostr); 8 document.write(hellostr); 9 } 10 //这里是对前面定义的函数进行调用 11 sayHello(); 12 </script>
练习:分别用for循环和while循环计算出1-100的和?
异常处理
1
2
3
4
5
6
7
8
9
10
|
try { //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 } catch (e) { // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。 //e是一个局部变量,用来指向Error对象或者其他抛出的对象 } finally { //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。 } |
注:主动抛出异常 throw Error('xxxx')
ECMA对象
从传统意义上来说,ECMAScript 并不真正具有类。事实上,除了说明不存在类,在 ECMA-262 中根本没有出现“类”这个词。ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。
var o = new Object();
对象的概念与分类:
- 由ECMAScript定义的本地对象.独立于宿主环境的 ECMAScript 实现提供的对象.(native object)
- ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现.这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。(built-in object)
- 所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。
object对象:ECMAScript 中的所有对象都由这个对象继承而来;Object 对象中的所有属性和方法都会出现在其他对象中
ToString() : 返回对象的原始字符串表示。
ValueOf() : 返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。
11种内置对象
包括:
Array ,String , Date, Math, Boolean, Number Function, Global, Error, RegExp , Object
简介:
在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String、Math、Array、Date、RegExp都是JavaScript中重要的内置对象,在JavaScript程序大多数功能都是通过对象实现的
<script language="javascript"> var aa=Number.MAX_VALUE; //利用数字对象获取可表示最大数 var bb=new String("hello JavaScript"); //创建字符串对象 var cc=new Date(); //创建日期对象 var dd=new Array("星期一","星期二","星期三","星期四"); //数组对象 </script>
String对象
自动创建字符串对象:
1
2
3
|
var str1 = "hello world" ; alert(str1.length); alert(str1.substr( 1 , 5 )); |
调用字符串的对象属性或方法时自动创建对象,用完就丢弃
手工创建字符串对象
1
2
3
|
var str1 = new String( "hello word" ); alert(str1.length); alert(str1.substr( 1 , 3 )); |
采用new创建字符串对象str1,全局有效
String对象的属性
1
2
|
获取字符串长度 length |
var str1="String对象";
var str2="";
alert("str1长度 "+str1.length);
alert("str2长度 "+str2.length);
String对象的方法(1) —— 格式编排方法
格式编排方法返回值列表
1 书写格式: 2 3 String对象提供了一组针对HTML格式的方法,如x.anchor()返回锚定义字符串<a>x</a>, 4 x.bold()返回粗体表示字符串<b>x</b>,x.sup()返回上标格式字符串<sup>x</sup>。 5 ----------------------------------------- 6 7 var x="yuan"; 8 var y="x.italics():"+x.italics(); 9 document.write(y.fontsize(10));//<font size="10">x.italics():<i>yuan</i></font>
String对象的方法(2)—— 大小写转换
1 var str1="AbcdEfgh"; 2 3 var str2=str1.toLowerCase(); 4 var str3=str1.toUpperCase(); 5 alert(str2); 6 //结果为"abcdefgh" 7 alert(str3); 8 //结果为"ABCDEFGH"
String对象的方法(3) —— 获取指定字符
1 书写格式 2 3 x.charAt(index) 4 5 x.charCodeAt(index) 6 7 使用注解 8 9 x代表字符串对象 10 index代表字符位置 11 index从0开始编号 12 charAt返回index位置的字符 13 charCodeAt返回index位置的Unicode编码 14 ---------------------- 15 var str1="welcome to the world of JS! 苑昊"; 16 17 var str2=str1.charAt(28); 18 var str3=str1.charCodeAt(28); 19 alert(str2); 20 //结果为"苑" 21 alert(str3); 22 //结果为33489
String对象的方法(4)—— 查询字符串
1 //书写格式 2 // 3 //x.indexOf(findstr,index) 4 //x.lastIndexOf(findstr) 5 //------------------------------------- 6 var str1="welcome to the world of JS!"; 7 8 var str2=str1.indexOf("l"); 9 var str3=str1.lastIndexOf("l"); 10 alert(str2); 11 //结果为2 12 alert(str3); 13 //结果为18 14 15 //-------*********************************************************------- 16 17 //书写格式 18 // 19 //x.match(regexp) 20 // 21 //x.search(regexp) 22 // 23 //使用注解 24 // 25 //x代表字符串对象 26 // 27 //regexp代表正则表达式或字符串 28 // 29 //match返回匹配字符串的数组,如果没有匹配则返回null 30 // 31 //search返回匹配字符串的首字符位置索引 32 //------------------------------------- 33 var str1="welcome to the world of JS!"; 34 35 var str2=str1.match("world"); 36 var str3=str1.search("world"); 37 alert(str2[0]); 38 //结果为"world" 39 alert(str3); 40 //结果为15
String对象的方法(5) ——子字符串处理
截取子字符串
1 //截取子字符串 2 // 3 //书写格式 4 // 5 //x.substr(start, length) 6 // 7 //x.substring(start, end) 8 // 9 //使用注解 10 // 11 //x代表字符串对象 12 // 13 //start表示开始位置 14 // 15 //length表示截取长度 16 // 17 //end是结束位置加1 18 // 19 //第一个字符位置为0 20 21 22 var str1="abcdefgh"; 23 var str2=str1.substr(2,4); 24 var str3=str1.substring(2,4); 25 alert(str2); 26 //结果为"cdef" 27 alert(str3); 28 //结果为"cd" 29 30 //-------*********************************************************------- 31 //x.slice(start, end) 32 33 34 var str1="abcdefgh"; 35 var str2=str1.slice(2,4); 36 var str3=str1.slice(4); 37 var str4=str1.slice(2,-1); 38 var str5=str1.slice(-3,-1); 39 alert(str2); 40 //结果为"cd" 41 alert(str3); 42 //结果为"efgh" 43 alert(str4); 44 //结果为"cdefg" 45 alert(str5); 46 //结果为"fg"
替换子字符串
1 //x.replace(findstr,tostr) 2 3 var str1="abcdefgh"; 4 var str2=str1.replace("cd","aaa"); 5 alert(str2); 6 //结果为"abaaaefgh"
分割字符串
1 var str1="一,二,三,四,五,六,日"; 2 3 var strArray=str1.split(","); 4 5 alert(strArray[1]); 6 //结果为"二"
连接字符串
1 //y=x.concat(addstr) 2 // 3 //使用注解 4 // 5 //x代表字符串对象 6 //addstr为添加字符串 7 //返回x+addstr字符串 8 9 var str1="abcd"; 10 var str2=str1.concat("efgh"); 11 12 alert(str2); 13 //结果为"abcdefgh"
Array对象
创建数组对象
1 Array 对象用于在单个的变量中存储多个值。 2 语法: 3 4 创建方式1: 5 var a=[1,2,3]; 6 7 创建方式2: 8 new Array(); // 创建数组时允许指定元素个数也可以不指定元素个数。 9 new Array(size);//if 1个参数且为数字,即代表size,not content 10 初始化数组对象: 11 var cnweek=new Array(7); 12 cnweek[0]="星期日"; 13 cnweek[1]="星期一"; 14 ... 15 cnweek[6]="星期六"; 16 17 new Array(element0, element1, ..., elementn)//也可以直接在建立对象时初始化数组元素,元素类型允许不同 18 19 var test=new Array(100,"a",true);
创建二维数组
1 var cnweek=new Array(7); 2 for (var i=0;i<=6;i++){ 3 cnweek[i]=new Array(2); 4 } 5 cnweek[0][0]="星期日"; 6 cnweek[0][1]="Sunday"; 7 cnweek[1][0]="星期一"; 8 cnweek[1][1]="Monday"; 9 ... 10 cnweek[6][0]="星期六"; 11 cnweek[6][1]="Saturday";
Array对象的属性
获取数组元素的个数:length
1 var cnweek=new Array(7); 2 cnweek[0]="星期日"; 3 cnweek[1]="星期一"; 4 cnweek[2]="星期二"; 5 cnweek[3]="星期三"; 6 cnweek[4]="星期四"; 7 cnweek[5]="星期五"; 8 cnweek[6]="星期六"; 9 for (var i=0;i<cnweek.length;i++){ 10 document.write(cnweek[i]+" | "); 11 }
Array对象的方法
连接数组-join方法
1 //书写格式 2 //x.join(bystr) 3 //使用注解 4 // 5 //x代表数组对象 6 //bystr作为连接数组中元素的字符串 7 //返回连接后的字符串 8 //与字符串的split功能刚好相反 9 10 var arr1=[1, 2, 3, 4, 5, 6, 7]; 11 12 var str1=arr1.join("-"); 13 14 alert(str1); 15 //结果为"1-2-3-4-5-6-7"
连接数组-concat方法
1 //连接数组-concat方法 2 // 3 //x.concat(value,...) 4 5 6 var a = [1,2,3]; 7 var a = new Array(1,2,3); 8 var b=a.concat(4,5) ; 9 10 11 alert(a.toString()); 12 //返回结果为1,2,3 13 alert(b.toString()); 14 //返回结果为1,2,3,4,5
数组排序-reverse sort
1 //x.reverse() 2 //x.sort() 3 4 var arr1=[32, 12, 111, 444]; 5 //var arr1=["a","d","f","c"]; 6 7 arr1.reverse(); //颠倒数组元素 8 alert(arr1.toString()); 9 //结果为444,111,12,32 10 11 arr1.sort(); //排序数组元素 12 alert(arr1.toString()); 13 //结果为111,12,32,444 14 15 //------------------------------ 16 arr=[1,5,2,100]; 17 18 //arr.sort(); 19 //alert(arr); 20 //如果就想按着数字比较呢? 21 22 function intSort(a,b){ 23 if (a>b){ 24 return 1;//-1 25 } 26 else if(a<b){ 27 return -1;//1 28 } 29 else { 30 return 0 31 } 32 } 33 34 arr.sort(intSort); 35 36 alert(arr); 37 38 function IntSort(a,b){ 39 return a-b; 40 }
数组切片-slice
1 //x.slice(start, end) 2 // 3 //使用注解 4 // 5 //x代表数组对象 6 //start表示开始位置索引 7 //end是结束位置下一数组元素索引编号 8 //第一个数组元素索引为0 9 //start、end可为负数,-1代表最后一个数组元素 10 //end省略则相当于从start位置截取以后所有数组元素 11 12 var arr1=['a','b','c','d','e','f','g','h']; 13 var arr2=arr1.slice(2,4); 14 var arr3=arr1.slice(4); 15 var arr4=arr1.slice(2,-1); 16 17 alert(arr2.toString()); 18 //结果为"c,d" 19 alert(arr3.toString()); 20 //结果为"e,f,g,h" 21 alert(arr4.toString()); 22 //结果为"c,d,e,f,g"
删除子数组
1 //x. splice(start, deleteCount, value, ...) 2 // 3 //使用注解 4 // 5 //x代表数组对象 6 //splice的主要用途是对数组指定位置进行删除和插入 7 //start表示开始位置索引 8 //deleteCount删除数组元素的个数 9 //value表示在删除位置插入的数组元素 10 //value参数可以省略 11 12 13 var a = [1,2,3,4,5,6,7,8]; 14 a.splice(1,2); 15 //a变为 [1,4,5,6,7,8] 16 alert(a.toString()); 17 a.splice(1,1); 18 //a变为[1,5,6,7,8] 19 alert(a.toString()); 20 a.splice(1,0,2,3); 21 //a变为[1,2,3,5,6,7,8] 22 alert(a.toString());
数组的进出栈操作(1)
1 //push pop这两个方法模拟的是一个栈操作 2 3 //x.push(value, ...) 压栈 4 //x.pop() 弹栈 5 //使用注解 6 // 7 //x代表数组对象 8 //value可以为字符串、数字、数组等任何值 9 //push是将value值添加到数组x的结尾 10 //pop是将数组x的最后一个元素删除 11 12 13 var arr1=[1,2,3]; 14 arr1.push(4,5); 15 alert(arr1); 16 //结果为"1,2,3,4,5" 17 arr1.push([6,7]); 18 alert(arr1) 19 //结果为"1,2,3,4,5,6,7" 20 arr1.pop(); 21 alert(arr1); 22 //结果为"1,2,3,4,5"
数组的进出栈操作(2)
1 // unshift shift 2 //x.unshift(value,...) 3 //x.shift() 4 //使用注解 5 // 6 //x代表数组对象 7 //value可以为字符串、数字、数组等任何值 8 //unshift是将value值插入到数组x的开始 9 //shift是将数组x的第一个元素删除 10 11 var arr1=[1,2,3]; 12 arr1.unshift(4,5); 13 alert(arr1); 14 //结果为"4,5,1,2,3" 15 arr1. unshift([6,7]); 16 alert(arr1); 17 //结果为"6,7,4,5,1,2,3" 18 arr1.shift(); 19 alert(arr1); 20 //结果为"4,5,1,2,3"
添加或删除数组中的元素-splice
删除: 数组.splice(从哪个索引位置开始删,要删除的个数) 例:arr=['alex','eric','eva'] arr.splice(1,1) //会返回被删的元素 ['eric'] console.log(arr) //arr变为 ['alex','eva'] 添加: 数组.splice(0,0,要添加的元素,要添加的元素,...) 例:arr=['alex','eva'] arr.splice(0,0,'eric','alvin') // [] console.log(arr) // ['eric','alvin','alex','eva']
总结js的数组特性:
1 // js中数组的特性 2 //java中数组的特性, 规定是什么类型的数组,就只能装什么类型.只有一种类型. 3 //js中的数组特性1: js中的数组可以装任意类型,没有任何限制. 4 //js中的数组特性2: js中的数组,长度是随着下标变化的.用到多长就有多长. 5 var arr5 = ['abc',123,1.14,true,null,undefined,new String('1213'),new Function('a','b','alert(a+b)')]; 6 /* alert(arr5.length);//8 7 arr5[10] = "hahaha"; 8 alert(arr5.length); //11 9 alert(arr5[9]);// undefined */
Date对象
创建Date对象
1 //方法1:不指定参数 2 var nowd1=new Date(); 3 alert(nowd1.toLocaleString( )); 4 //方法2:参数为日期字符串 5 var nowd2=new Date("2004/3/20 11:12"); 6 alert(nowd2.toLocaleString( )); 7 var nowd3=new Date("04/03/20 11:12"); 8 alert(nowd3.toLocaleString( )); 9 //方法3:参数为毫秒数 10 var nowd3=new Date(5000); 11 alert(nowd3.toLocaleString( )); 12 alert(nowd3.toUTCString()); 13 14 //方法4:参数为年月日小时分钟秒毫秒 15 var nowd4=new Date(2004,2,20,11,12,0,300); 16 alert(nowd4.toLocaleString( )); 17 //毫秒并不直接显示
Date对象的方法—获取日期和时间
1 获取日期和时间 2 getDate() 获取日 3 getDay () 获取星期 4 getMonth () 获取月(0-11) 5 getFullYear () 获取完整年份 6 getYear () 获取年 7 getHours () 获取小时 8 getMinutes () 获取分钟 9 getSeconds () 获取秒 10 getMilliseconds () 获取毫秒 11 getTime () 返回累计毫秒数(从1970/1/1午夜)
练习实例:
function getCurrentDate(){ //1. 创建Date对象 var date = new Date(); //没有填入任何参数那么就是当前时间 //2. 获得当前年份 var year = date.getFullYear(); //3. 获得当前月份 js中月份是从0到11. var month = date.getMonth()+1; //4. 获得当前日 var day = date.getDate(); //5. 获得当前小时 var hour = date.getHours(); //6. 获得当前分钟 var min = date.getMinutes(); //7. 获得当前秒 var sec = date.getSeconds(); //8. 获得当前星期 var week = date.getDay(); //没有getWeek // 2014年06月18日 15:40:30 星期三 return year+"年"+changeNum(month)+"月"+day+"日 "+hour+":"+min+":"+sec+" "+parseWeek(week); } alert(getCurrentDate()); //解决 自动补齐成两位数字的方法 function changeNum(num){ if(num < 10){ return "0"+num; }else{ return num; } } //将数字 0~6 转换成 星期日到星期六 function parseWeek(week){ var arr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]; // 0 1 2 3 ............. return arr[week]; }
Date对象的方法—设置日期和时间
1 //设置日期和时间 2 //setDate(day_of_month) 设置日 3 //setMonth (month) 设置月 4 //setFullYear (year) 设置年 5 //setHours (hour) 设置小时 6 //setMinutes (minute) 设置分钟 7 //setSeconds (second) 设置秒 8 //setMillliseconds (ms) 设置毫秒(0-999) 9 //setTime (allms) 设置累计毫秒(从1970/1/1午夜) 10 11 var x=new Date(); 12 x.setFullYear (1997); //设置年1997 13 x.setMonth(7); //设置月7 14 x.setDate(1); //设置日1 15 x.setHours(5); //设置小时5 16 x.setMinutes(12); //设置分钟12 17 x.setSeconds(54); //设置秒54 18 x.setMilliseconds(230); //设置毫秒230 19 document.write(x.toLocaleString( )+"<br>"); 20 //返回1997年8月1日5点12分54秒 21 22 x.setTime(870409430000); //设置累计毫秒数 23 document.write(x.toLocaleString( )+"<br>"); 24 //返回1997年8月1日12点23分50秒
Date对象的方法—日期和时间的转换
1 日期和时间的转换: 2 3 getTimezoneOffset():8个时区×15度×4分/度=480; 4 返回本地时间与GMT的时间差,以分钟为单位 5 toUTCString() 6 返回国际标准时间字符串 7 toLocalString() 8 返回本地格式时间字符串 9 Date.parse(x) 10 返回累计毫秒数(从1970/1/1午夜到本地时间) 11 Date.UTC(x) 12 返回累计毫秒数(从1970/1/1午夜到国际时间)
RegExp对象
js正则表达式processon:https://www.processon.com/view/link/5b3d87d8e4b00c2f18be35e4#map
1 //RegExp对象 2 // 在表单验证时使用该对象验证用户填入的字符串是否符合规则. 3 //创建正则对象方式1 参数1 正则表达式 参数2 验证模式 g global / i 忽略大小写. //参数2一般填写g就可以,也有“gi”. 4 // 用户名 首字母必须是英文, 除了第一位其他只能是英文数字和_ . 长度最短不能少于6位 最长不能超过12位 5 //----------------------------创建方式1 6 /* var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$","g"); 7 // 8 //验证字符串 9 var str = "bc123"; 10 alert(reg1.test(str));// true 11 12 //----------------------------创建方式2 /填写正则表达式/匹配模式; 13 var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/g; 14 15 alert(reg2.test(str));// true 16 */ 17 //-------------------------------正则对象的方法------------------- 18 //test方法 ==> 测试一个字符串是否复合 正则规则. 返回值是true 和false. 19 20 //-------------------------String 中与正则结合的4个方法------------------. 21 // macth search split replace 22 var str = "hello world"; 23 24 //alert(str.match(/o/g)); //查找字符串中 复合正则的 内容. 25 //alert(str.search(/h/g));// 0 查找字符串中符合正则表达式的内容位置 26 //alert(str.split(/o/g)); // 按照正则表达式对字符串进行切割. 返回数组; 27 alert(str.replace(/o/g, "s")); // hells wsrld 对字符串按照正则进行替换.
Math对象
1 //Math对象 2 //该对象中的属性方法 和数学有关. 3 //Math是内置对象 , 与Global的不同之处是, 在调用时 需要打出 "Math."前缀. 4 //属性学习: 5 //alert(Math.PI); 6 //方法学习: 7 //alert(Math.random()); // 获得随机数 0~1 不包括1. 8 //alert(Math.round(1.5)); // 四舍五入 9 //练习:获取1-100的随机整数,包括1和100 10 //var num=Math.random(); 11 //num=num*10; 12 //num=Math.round(num); 13 // alert(num) 14 //============max min========================= 15 /* alert(Math.max(1,2));// 2 16 alert(Math.min(1,2));// 1 */ 17 //-------------pow-------------------------------- 18 alert(Math.pow(2,4));// pow 计算参数1 的参数2 次方. 19 20 21 22 23 abs(x) 返回数的绝对值。 24 exp(x) 返回 e 的指数。 25 floor(x)对数进行下舍入。 26 log(x) 返回数的自然对数(底为e)。 27 max(x,y) 返回 x 和 y 中的最高值。 28 min(x,y) 返回 x 和 y 中的最低值。 29 pow(x,y) 返回 x 的 y 次幂。 30 random() 返回 0 ~ 1 之间的随机数。 31 round(x) 把数四舍五入为最接近的整数。 32 sin(x) 返回数的正弦。 33 sqrt(x) 返回数的平方根。 34 tan(x) 返回角的正切。
Function 对象(重点)
函数的定义:
1
2
3
|
function 函数名 (参数){
函数体; return 返回值; } |
功能说明:
- 可以使用变量、常量或表达式作为函数调用的参数
- 函数由关键字function定义
- 函数名的定义规则与标识符一致,大小写是敏感的
- 返回值必须使用return
Function 类可以表示开发者定义的任何函数。
用 Function 类直接创建函数的语法如下:
function 函数名 (参数){
函数体;
return 返回值;
}
//another way:
var 函数名 = new Function("参数1","参数n","function_body");
虽然由于字符串的关系,第二种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确创建的函数行为是相同的。
实例:
1
2
3
4
5
6
7
8
9
10
11
12
|
alert(1); function func1(){ alert( 'hello yuan!' ); return 8 } ret=func1(); alert(ret) ---------------- var func1= new Function( "name" , "alert(\"hello\"+name);" ) func1( "yuan" ) |
注意:js的函数加载执行与python不同,它是整体加载完才会执行,所以执行函数放在函数声明上面或下面都可以:
1 <script> 2 //f(); --->OK 3 4 function f(){ 5 console.log("hello") 6 7 } 8 9 f() //----->OK 10 </script>
Function 对象的 length 属性
如前所述,函数属于引用类型,所以它们也有属性和方法。
比如,ECMAScript 定义的属性 length 声明了函数期望的参数个数。
1
|
alert(func1.length) |
Function 对象的方法
Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。这两个方法返回的都是函数的源代码,在调试时尤其有用。
1
|
alert(void(fun1(1,2))) |
运算符void()作用:拦截方法的返回值
函数的调用
1 function func1(a,b){ 2 3 alert(a+b); 4 } 5 6 func1(1,2); //3 7 func1(1,2,3);//3 8 func1(1); //NaN 9 func1(); //NaN 10 11 //只要函数名写对即可,参数怎么填都不报错. 12 13 -------------------面试题----------- 14 function a(a,b){ 15 alert(a+b); 16 } 17 18 var a=1; 19 var b=2; 20 a(a,b)
函数的内置对象arguments
1 function add(a,b){ 2 3 console.log(a+b);//3 4 console.log(arguments.length);//2 5 console.log(arguments);//[1,2] 6 7 } 8 add(1,2) 9 10 ------------------arguments的用处1 ------------------ 11 function nxAdd(){ 12 var result=0; 13 for (var num in arguments){ 14 result+=arguments[num] 15 } 16 alert(result) 17 18 } 19 20 nxAdd(1,2,3,4,5) 21 22 // ------------------arguments的用处2 ------------------ 23 24 function f(a,b,c){ 25 if (arguments.length!=3){ 26 throw new Error("function f called with "+arguments.length+" arguments,but it just need 3 arguments") 27 } 28 else { 29 alert("success!") 30 } 31 } 32 33 f(1,2,3,4,5)
匿名函数
1 // 匿名函数 2 var func = function(arg){ 3 return "tony"; 4 } 5 6 // 匿名函数的应用 7 (function(){ 8 alert("tony"); 9 } )() 10 11 (function(arg){ 12 console.log(arg); 13 })('123')
注:自执行函数,解决了全局污染的问题
函数的作用域链和闭包
作用域
js的作用域和py相似,if while等控制语句并没有自己作用域;而函数是有自己的作用域的;
if(1==1){
var s=12; } console.log(s);//12 // ---------------------- function f(){ var temp=666; } f(); console.log(temp);//Uncaught ReferenceError: temp is not defined
嵌套函数的作用域:
例1:
var city = 'beijing'; function func(){ var city = 'shanghai'; function inner(){ var city = 'shenzhen'; console.log(city); } inner(); } func();
例2:
var city = 'beijing'; function Bar(){ console.log(city); } function func(){ var city = 'shanghai'; return Bar; } var ret = func(); ret(); //beijing
闭包:
var city = 'beijing'; function func(){ var city = "shanghai"; function inner(){ // var city = "langfang"; console.log(city); } return inner; } var ret = func(); ret();
思考题1:
1 var city = 'beijing'; 2 3 function func(){ 4 var city = "shanghai"; 5 6 function inner(){ 7 // var city = "langfang"; 8 console.log(city); 9 } 10 11 return inner; 12 } 13 14 var ret = func(); 15 ret(); 16 17 18 var city = 'beijing'; 19 20 function Bar(){ 21 console.log(city); 22 } 23 24 function func(){ 25 26 var city = 'shanghai'; 27 return Bar; 28 } 29 30 var ret = func(); 31 ret(); //beijing
作用域链(Scope Chain):
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
var x=1; function foo() { var y = 2; function bar() { var z = 3; } } #bar的作用域链: barScopeChain=[bar.AO, foo.AO, global.VO];
#foo的作用域链: fooScopeChain=[foo.Ao, global.VO];
1 什么是AO,VO? 2 在函数创建时,每个函数都会创建一个活动对象Active Object(AO),全局对象为Global Object(VO),创建函数的过程也就是为这个对象添加属性的过程,作用域链就是由这些绑定了属性的活动对象构成的。 3 例如:找x变量;bar函数在搜寻变量x的过程中,先从自身AO对象上找,如果bar.AO存在这个属性,那么会直接使用这个属性的值,如果不存在,则会转到父级函数的AO对象,也就是foo.AO 4 如果找到x属性则使用,找不到继续 在global.VO对象查找,找到x的属性,返回属性值。如果在global.VO中没有找到,则会抛出异常ReferenceError 5 6 执行上下文。 7 函数在执行时会创建一个称为“执行上下文(execution context)”的内部对象,执行上下文定义了函数 8 执行时的环境。每个执行上下文都有自己的作用域链,用于标识符解析,当执行上下文被创建时,而它的作用 9 域链初始化为当前运行函数的[[Scope]]所包含的对象。 10 函数执行 11 在函数执行过程中,每遇到一个变量,都会检索从哪里获取和存储数据,该过程从作用域链头部,也就是从活 12 动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没有则继续搜索作用域 13 链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义,函数执行过程中,每个标识符都 14 要经历这样的搜索过程。
1 函数进入全局,创建VO对象,绑定x属性<入栈> 2 global.VO={x=underfind; foo:reference of function}(这里只是预解析,为AO对象绑定声明的属性,函数执行时才会执行赋值语句,所以值是underfind) 3 遇到foo函数,创建foo.AO,绑定y属性<入栈> 4 foo.AO={y=underfind, bar:reference of function} 5 遇到bar函数,创建bar.AO,绑定z属性<入栈> 6 bar.AO={z:underfind} 7 作用域链和执行上下文都会保存在堆栈中,所以: 8 bar函数的scope chain为:[0]bar.AO-->[1]foo.AO-->[2]global.VO 9 10 foo函数的scope chain为:[0]foo.AO-->[1]global.Vo 11 //建议:少定义全局变量 12 //理由:因为作用域链是栈的结构,全局变量在栈底,每次访问全局变量都会遍历一次栈,//这样会影响效率
函数的scope等于自身的AO对象加上父级的scope,也可以理解为一个函数的作用域等于自身活动对象加上父级作用域.
函数执行前后的作用域链:
注意:作用域链的非自己部分在函数对象被建立(函数声明、函数表达式)的时候建立,而不需要等到执行
思考题2:
1 for (var i=1; i<=9; i++) { 2 setTimeout( function timer(){ 3 console.log( i ); 4 },1000 ); 5 } 6 7 //================== 8 9 for (var i=1; i<=9; i++) { 10 (function(){ 11 var j = i; 12 setTimeout( function timer(){ 13 console.log( j ); 14 }, 1000 ); 15 })();
BOM对象
BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。
使 JavaScript 有能力与浏览器“对话”。
window对象
window对象 所有浏览器都支持 window 对象。 概念上讲.一个html文档对应一个window对象. 功能上讲: 控制浏览器窗口的. 使用上讲: window对象不需要创建对象,直接使用即可.
Window 对象方法
1 alert() 显示带有一段消息和一个确认按钮的警告框。 2 confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。 3 prompt() 显示可提示用户输入的对话框。 4 5 open() 打开一个新的浏览器窗口或查找一个已命名的窗口。 6 close() 关闭浏览器窗口。 7 setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。 8 clearInterval() 取消由 setInterval() 设置的 timeout。 9 setTimeout() 在指定的毫秒数后调用函数或计算表达式。 10 clearTimeout() 取消由 setTimeout() 方法设置的 timeout。 11 scrollTo() 把内容滚动到指定的坐标。
交互方法:
1 方法讲解: 2 //----------alert confirm prompt---------------------------- 3 //alert('aaa'); 4 5 6 /* var result = confirm("您确定要删除吗?"); 7 alert(result); */ 8 9 //prompt 参数1 : 提示信息. 参数2:输入框的默认值. 返回值是用户输入的内容. 10 11 // var result = prompt("请输入一个数字!","haha"); 12 // alert(result); 13 14 15 16 方法讲解: 17 //open方法 打开和一个新的窗口 并 进入指定网址.参数1 : 网址. 18 //调用方式1 19 //open("http://www.baidu.com"); 20 //参数1 什么都不填 就是打开一个新窗口. 参数2.填入新窗口的名字(一般可以不填). 参数3: 新打开窗口的参数. 21 open('','','width=200,resizable=no,height=100'); // 新打开一个宽为200 高为100的窗口 22 //close方法 将当前文档窗口关闭. 23 //close();
练习:
1 var num = Math.round(Math.random()*100); 2 function acceptInput(){ 3 //2.让用户输入(prompt) 并接受 用户输入结果 4 var userNum = prompt("请输入一个0~100之间的数字!","0"); 5 //3.将用户输入的值与 随机数进行比较 6 if(isNaN(+userNum)){ 7 //用户输入的无效(重复2,3步骤) 8 alert("请输入有效数字!"); 9 acceptInput(); 10 } 11 else if(userNum > num){ 12 //大了==> 提示用户大了,让用户重新输入(重复2,3步骤) 13 alert("您输入的大了!"); 14 acceptInput(); 15 }else if(userNum < num){ 16 //小了==> 提示用户小了,让用户重新输入(重复2,3步骤) 17 alert("您输入的小了!"); 18 acceptInput(); 19 }else{ 20 //答对了==>提示用户答对了 , 询问用户是否继续游戏(confirm). 21 var result = confirm("恭喜您!答对了,是否继续游戏?"); 22 if(result){ 23 //是 ==> 重复123步骤. 24 num = Math.round(Math.random()*100); 25 acceptInput(); 26 }else{ 27 //否==> 关闭窗口(close方法). 28 close(); 29 } 30 }
setInterval clearInterval
1 <input type="text" id="clock" style="width: 249px"> 2 <input type="button" value="begin" onclick="begin_click()"> 3 <input type="button" value="End" onclick="End()"> 4 <!--<input type="button" value="timeout" onclick="f1()">--> 5 <script> 6 <!--function f1() {--> 7 <!--var ID=setTimeout(Timeout,1000);--> 8 <!--clearTimeout(ID)--> 9 <!--}--> 10 function begin() { 11 var Ntime=new Date().toLocaleString();; 12 var ret=document.getElementById("clock"); 13 ret.value=Ntime; 14 } 15 var ID; 16 function begin_click() { 17 if (ID==undefined){ 18 begin(); 19 ID=setInterval(begin,1000); 20 } 21 } 22 function End() { 23 clearInterval(ID); 24 ID=undefined; 25 } 26 </script>
setTimeout clearTimeout
1 var ID = setTimeout(abc,2000); // 只调用一次对应函数. 2 clearTimeout(ID); 3 function abc(){ 4 alert('aaa'); 5 }
History 对象
History 对象属性
History 对象包含用户(在浏览器窗口中)访问过的 URL。
History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问。
1
|
length 返回浏览器历史列表中的 URL 数量。 |
History 对象方法
back() 加载 history 列表中的前一个 URL。 forward() 加载 history 列表中的下一个 URL。 go() 加载 history 列表中的某个具体页面。
1 <a href="rrr.html">click</a> 2 <button onclick=" history.forward()">>>></button> 3 <button onclick="history.back()">back</button> 4 <button onclick="history.go()">back</button>
Location 对象
Location 对象包含有关当前 URL 的信息。
Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问。
Location 对象方法
location.assign(URL) location.reload() location.replace(newURL)//注意与assign的区别
DOM对象(DHTML)
7.1 什么是 DOM?
DOM 是 W3C(万维网联盟)的标准。DOM 定义了访问 HTML 和 XML 文档的标准:
"W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。"
W3C DOM 标准被分为 3 个不同的部分:
- 核心 DOM - 针对任何结构化文档的标准模型
- XML DOM - 针对 XML 文档的标准模型
- HTML DOM - 针对 HTML 文档的标准模型
- 什么是 XML DOM? ---->XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。
- 什么是 HTML DOM?---->HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
7.2 DOM 节点
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点(NODE):
- 整个文档是一个文档节点(document对象)
- 每个 HTML 元素是元素节点(element 对象)
- HTML 元素内的文本是文本节点(text对象)
- 每个 HTML 属性是属性节点(attribute对象)
- 注释是注释节点(comment对象)
画dom树是为了展示文档中各个对象之间的关系,用于对象的导航。
节点(自身)属性:
- attributes - 节点(元素)的属性节点
- nodeType – 节点类型
- nodeValue – 节点值
- nodeName – 节点名称
- innerHTML - 节点(元素)的文本值
导航属性:
- parentNode - 节点(元素)的父节点 (推荐)
- firstChild – 节点下第一个子元素
- lastChild – 节点下最后一个子元素
- childNodes - 节点(元素)的子节点
注意:
1 <div id="div1"> 2 <div id="div2"></div> 3 <p>hello yuan</p> 4 </div> 5 6 <script> 7 var div=document.getElementById("div2"); 8 9 console.log(div.nextSibling.nodeName); //思考:为什么不是P? 10 </script>
推荐导航属性:
1 parentElement // 父节点标签元素 2 3 children // 所有子标签 4 5 firstElementChild // 第一个子标签元素 6 7 lastElementChild // 最后一个子标签元素 8 9 nextElementtSibling // 下一个兄弟标签元素 10 11 previousElementSibling // 上一个兄弟标签元素
节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的子
- 同胞是拥有相同父节点的节点
下面的图片展示了节点树的一部分,以及节点之间的关系:
访问 HTML 元素(节点),访问 HTML 元素等同于访问节点,我们能够以不同的方式来访问 HTML 元素:
页面查找:
- 通过使用 getElementById() 方法
- 通过使用 getElementsByTagName() 方法
- 通过使用 getElementsByClassName() 方法
- 通过使用 getElementsByName() 方法
局部查找:
1 <div id="div1"> 2 3 <div class="div2">i am div2</div> 4 <div name="yuan">i am div2</div> 5 <div id="div3">i am div2</div> 6 <p>hello p</p> 7 </div> 8 9 <script> 10 11 var div1=document.getElementById("div1"); 12 13 ////支持; 14 // var ele= div1.getElementsByTagName("p"); 15 // alert(ele.length); 16 ////支持 17 // var ele2=div1.getElementsByClassName("div2"); 18 // alert(ele2.length); 19 ////不支持 20 // var ele3=div1.getElementById("div3"); 21 // alert(ele3.length); 22 ////不支持 23 // var ele4=div1.getElementsByName("yuan"); 24 // alert(ele4.length) 25 26 </script>
7.3 HTML DOM Event(事件)
HTML 4.0 的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript。下面是一个属性列表,这些属性可插入 HTML 标签来定义事件动作。
onclick 当用户点击某个对象时调用的事件句柄。 ondblclick 当用户双击某个对象时调用的事件句柄。 onfocus 元素获得焦点。 //练习:输入框 onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证. onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动) onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交. onkeypress 某个键盘按键被按下并松开。 onkeyup 某个键盘按键被松开。 onload 一张页面或一幅图像完成加载。 onmousedown 鼠标按钮被按下。
onmouseup 鼠标被按下 onmousemove 鼠标被移动。 onmouseout 鼠标从某元素移开。 onmouseover 鼠标移到某元素之上。
onmouseenter 鼠标移到某元素之上
onmouseleave 鼠标从元素离开 onselect 文本被选中。 onsubmit 确认按钮被点击。
注:onmouseover 当穿过父元素和子元素 都会调用
onmouseenter 只穿过父元素 才会调用
两种为元素附加事件属性的方式
1 <div onclick="alert(123)">点我呀</div> 2 <p id="abc">试一试!</p> 3 4 <script> 5 var ele=document.getElementById("abc"); 6 7 8 ele.onclick=function(){ 9 alert("hi"); 10 }; 11 12 </script>
注意:
1 <div id="abc" onclick="func1(this)">事件绑定方式1</div> 2 <div id="id123">事件绑定方式2</div> 3 <script> 4 function func1(self){ 5 console.log(self.id) 6 } 7 8 //jquery下是$(self), 这种方式this参数必须填写; 9 10 //------------------------------------------ 11 var ele=document.getElementById("id123").onclick=function(){ 12 console.log(this.id); 13 //jquery下是$(this), 这种方式不需要this参数; 14 } 15 16 </script>
onload:
onload 属性开发中 只给 body元素加.
这个属性的触发 标志着 页面内容被加载完成.
应用场景: 当有些事情我们希望页面加载完立刻执行,那么可以使用该事件属性.
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 7 <script> 8 // window.onload=function(){ 9 // var ele=document.getElementById("ppp"); 10 // ele.onclick=function(){ 11 // alert(123) 12 // }; 13 // }; 14 15 16 17 function fun1() { 18 var ele=document.getElementById("ppp"); 19 ele.onclick=function(){ 20 alert(123) 21 }; 22 } 23 24 </script> 25 </head> 26 <body onload="fun1()"> 27 28 <p id="ppp">hello p</p> 29 30 </body> 31 </html>
onsubmit:
是当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.
1 <form id="form"> 2 <input type="text"/> 3 <input type="submit" value="点我!" /> 4 </form> 5 6 <script type="text/javascript"> 7 //阻止表单提交方式1(). 8 //onsubmit 命名的事件函数,可以接受返回值. 其中返回false表示拦截表单提交.其他为放行. 9 10 var ele=document.getElementById("form"); 11 ele.onsubmit=function(event) { 12 // alert("验证失败 表单不会提交!"); 13 // return false; 14 15 // 阻止表单提交方式2 event.preventDefault(); ==>通知浏览器不要执行与事件关联的默认动作。 16 alert("验证失败 表单不会提交!"); 17 event.preventDefault(); 18 19 }
Event 对象
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传给事件函数.我们获得仅仅需要接收一下即可.
比如onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就时KeyCode;
思考:onclick=function(event){};这个方法是谁调用的?
事件传播:
1 <div id="abc_1" style="border:1px solid red;width:300px;height:300px;"> 2 <div id="abc_2" style="border:1px solid red;width:200px;height:200px;"> 3 4 </div> 5 </div> 6 <script type="text/javascript"> 7 document.getElementById("abc_1").onclick=function(){ 8 alert('111'); 9 } 10 document.getElementById("abc_2").onclick=function(event){ 11 alert('222'); 12 event.stopPropagation(); //阻止事件向外层div传播. 13 } 14 15 </script>
js事件流:
事件流描述的是从页面中接收事件的顺序
1、DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:
① 事件捕获阶段;
② 处于目标阶段;
③ 事件冒泡阶段
那么其实呢,js中还有另外一种绑定事件的方式:看下面代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件流</title> <script> window.onload = function(){ var oBtn = document.getElementById('btn'); oBtn.addEventListener('click',function(){ console.log('btn处于事件捕获阶段'); }, true); oBtn.addEventListener('click',function(){ console.log('btn处于事件冒泡阶段'); }, false); document.addEventListener('click',function(){ console.log('document处于事件捕获阶段'); }, true); document.addEventListener('click',function(){ console.log('document处于事件冒泡阶段'); }, false); document.documentElement.addEventListener('click',function(){ console.log('html处于事件捕获阶段'); }, true); document.documentElement.addEventListener('click',function(){ console.log('html处于事件冒泡阶段'); }, false); document.body.addEventListener('click',function(){ console.log('body处于事件捕获阶段'); }, true); document.body.addEventListener('click',function(){ console.log('body处于事件冒泡阶段'); }, false); }; </script> </head> <body> <a href="javascript:;" id="btn">按钮</a> </body> </html>
当我们点击这个btn的时候,看看页面都输出了什么:
在解释输出结果为什么是这样之前,还有几个知识点需要了解一下:
1、addEventListener
addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
2、document、documentElement和document.body三者之间的关系:
document代表的是整个html页面;
document.documentElement代表的是<html>
标签;
document.body代表的是<body>
标签;
接着我们就来聊聊上面的例子中输出的结果为什么是这样:
在标准的“DOM2级事件”中规定,事件流首先是经过事件捕获阶段,接着是处于目标阶段,最后是事件冒泡阶段。这里可以画个图示意一下:
首先在事件捕获过程中,document对象首先接收到click事件,然后事件沿着DOM树依次向下,一直传播到事件的实际目标,就是id为btn的a标签。
接着在事件冒泡过程中,事件开始时由最具体的元素(a标签)接收,然后逐级向上传播到较为不具体的节点(document)。
需要注意的点:由于老版本的浏览器不支持事件捕获,因此在实际开发中需要使用事件冒泡,在由特殊需要时再使用事件捕获
1、IE中的事件流只支持“事件冒泡”,但是版本到了IE9+以后,实现了“DOM2级事件”,也就是说IE9+以后也可以在捕获阶段对元素进行相应的操作。
2、在DOM事件流中,实际的目标在“捕获阶段”不会接收到事件。而是在“处于目标阶段”被触发,并在事件处理中被看成“冒泡阶段”的一部分。然后,“冒泡阶段”发生,事件又传播回文档。
关于event对象
- 在触发的事件的函数里面我们会接收到一个event对象,通过该对象我们需要的一些参数,比如说我们需要知道此事件作用到谁身上了,就可以通过event的属性
target
来获取到(IE暂且不谈),或者想阻止浏览器的默认行为可以通过方法preventDefault()
来进行阻止.以下是event对象的一些属性和方法
属性 | 描述 |
---|---|
altKey | 返回当事件被触发时,”ALT” 是否被按下。 |
button | 返回当事件被触发时,哪个鼠标按钮被点击。 |
clientX | 返回当事件被触发时,鼠标指针的水平坐标。 |
clientY | 返回当事件被触发时,鼠标指针的垂直坐标。 |
ctrlKey | 返回当事件被触发时,”CTRL” 键是否被按下。 |
metaKey | 返回当事件被触发时,”meta” 键是否被按下。 |
relatedTarget | 返回与事件的目标节点相关的节点。 |
screenX | 返回当某个事件被触发时,鼠标指针的水平坐标。 |
screenY | 返回当某个事件被触发时,鼠标指针的垂直坐标。 |
shiftKey | 返回当事件被触发时,”SHIFT” 键是否被按下 |
IE
属性(除了上面的鼠标/事件属性,IE 浏览器还支持下面的属性)
属性 | 描述 |
---|---|
cancelBubble |
如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。 |
fromElement | 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。 |
keyCode | 对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup |
offsetX,offsetY | 发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。 |
returnValue |
如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 |
srcElement |
对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。 |
toElement | 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。 |
x,y | 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。 |
- 标准 Event 属性 下面列出了 2 级 DOM 事件标准定义的属性。
属性和方法 | 描述 |
---|---|
bubbles | 返回布尔值,指示事件是否是起泡事件类型。 |
cancelable |
返回布尔值,指示事件是否可拥可取消的默认动作。 |
currentTarget |
返回其事件监听器触发该事件的元素。 |
eventPhase | 返回事件传播的当前阶段。 |
target |
返回触发此事件的元素(事件的目标节点)。 |
timeStamp | 返回事件生成的日期和时间。 |
type |
返回当前 Event 对象表示的事件的名称。 |
initEvent() | 初始化新创建的 Event 对象的属性。 |
preventDefault() |
通知浏览器不要执行与事件关联的默认动作。 |
stopPropagation() |
不再派发事件。 |
Event对象的一些兼容性写法(了解)
- 获得event对象兼容性写法
event || (event = window.event);
- 获得target兼容型写法
event.target||event.srcElement
- 阻止浏览器默认行为兼容性写法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
- 阻止冒泡写法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
7.4 增删改查演示
7.4.1 node的CURD:
增:
1
2
|
createElement(name)创建元素 appendChild();将元素添加 |
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 abc{ 8 width: 100px; 9 height: 100px; 10 background-color: red; 11 display: block; 12 } 13 </style> 14 </head> 15 <body> 16 <div id="box"> 17 <p id="child1">alex</p> 18 </div> 19 <script> 20 var oDiv = document.getElementById('box'); 21 var op1 = document.getElementById('child1'); 22 var op2 = document.createElement('p'); 23 op2.innerText = 'wusir'; 24 oDiv.insertBefore(op2, op1); 25 </script> 26 </body> 27 </html> 28 29 wusir 30 alex
删:
1
2
3
|
获得要删除的元素 获得它的父元素 使用removeChild()方法删除 |
改:
第一种方式:
使用上面增和删结合完成修改
第二中方式:
使用setAttribute();方法修改属性
使用innerHTML属性修改元素的内容
查: 使用之前介绍的方法.
1 控制元素显示隐藏 2 应用:网页中频繁性的切换建议使用这个 3 1.控制style.display属性显示隐藏 4 2.控制className对元素显示隐藏 5 6 问题: 初始化的时候有渲染, 7 8 应用:网页中少量的切换建议使用 9 3.对元素的创建和销毁 10 生命周期 出生 入死
1 <script type="text/javascript"> 2 //在第一个div中动态增加一个a标签. 该a标签点击之后跳转到百度首页. 3 function addNode(){ 4 //1.获得 第一个div 5 var div = document.getElementById("div_1"); 6 //2.创建a标签 createElement==>创建一个a标签 <a></a> 7 var eleA = document.createElement("a"); 8 //3.为a标签添加属性 <a href="http://www.baidu.com"></a> 9 eleA.setAttribute("href", "http://www.baidu.com"); 10 //4.为a标签添加内容 <a href="http://www.baidu.com">百度</a> 11 eleA.innerHTML = "百度"; 12 //5.将a标签添加到div中 13 div.appendChild(eleA); 14 } 15 //点击后 删除div区域2 16 function deleteNode(){ 17 //1 获得要删除的div区域 18 var div = document.getElementById("div_2"); 19 //2.获得父亲 20 var parent = div.parentNode; 21 //3 由父亲操刀 22 parent.removeChild(div); 23 } 24 //点击后 替换div区域3 为一个美女 25 function updateNode(){ 26 //1 获得要替换的div区域3 27 var div = document.getElementById("div_3"); 28 //2创建img标签对象 <img /> 29 var img = document.createElement("img"); 30 //3添加属性 <img src="001.jpg" /> 31 img.setAttribute("src", "001.JPG"); 32 //4.获得父节点 33 var parent = div.parentNode; 34 //5.替换 35 parent.replaceChild(img, div); 36 } 37 //点击后 将div区域4 克隆一份 添加到页面底部 38 39 function copyNode(){ 40 //1.获取要克隆的div 41 var div = document.getElementById("div_4"); 42 //2.克隆 参数为true 那么克隆时克隆所有子元素. false 只克隆自己 43 var div_copy = div.cloneNode(true); 44 //3.获得父亲 45 var parent = div.parentNode; 46 //4.添加 47 parent.appendChild(div_copy); 48 } 49 50 51 </script>
7.4.2 修改 HTML DOM
- 改变 HTML 内容
改变元素内容的最简答的方法是使用 innerHTML ,innerText。
- 改变 CSS 样式
1
2
|
<p id= "p2" >Hello world!</p> document.getElementById( "p2" ).style.color= "blue" ;<br> .style.fontSize=48px |
- 改变 HTML 属性
elementNode.setAttribute(name,value)
elementNode.getAttribute(name)<-------------->elementNode.value(DHTML)
- 创建新的 HTML 元素
createElement(name)
- 删除已有的 HTML 元素
elementNode.removeChild(node)
- 关于class的操作
elementNode.className
elementNode.classList.add
elementNode.classList.remove
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 200px; 9 height: 200px; 10 background-color: red; 11 } 12 </style> 13 </head> 14 <body> 15 <button id="btn">隐藏</button> 16 <div id="box"></div> 17 <script> 18 var oBtn = document.getElementById('btn'); 19 var oDiv = document.getElementById('box'); 20 var isShow = true; 21 $('btn').onclick = function() { 22 if (isShow) { 23 $('box').style.display = 'none'; 24 isShow = false; 25 this.innerText = '显示'; 26 }else{ 27 $('box').style.display = 'block'; 28 isShow = true; 29 this.innerText = '隐藏'; 30 } 31 }; 32 </script> 33 34 </body> 35 </html>
1 1、client系列 2 代码如下: 3 4 <!DOCTYPE html> 5 <html> 6 <head> 7 <meta charset="UTF-8"> 8 <title></title> 9 <style type="text/css"> 10 .box{ 11 width: 200px; 12 height: 200px; 13 position: absolute; 14 border: 10px solid red; 15 /*margin: 10px 0px 0px 0px;*/ 16 padding: 80px; 17 } 18 </style> 19 </head> 20 <body> 21 <div class="box"> 22 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 23 </div> 24 </body> 25 <script type="text/javascript"> 26 /* 27 * clientTop 内容区域到边框顶部的距离 ,说白了,就是边框的高度 28 * clientLeft 内容区域到边框左部的距离,说白了就是边框的乱度 29 * clientWidth 内容区域+左右padding 可视宽度 30 * clientHeight 内容区域+ 上下padding 可视高度 31 * */ 32 33 var oBox = document.getElementsByClassName('box')[0]; 34 console.log(oBox.clientTop); 35 console.log(oBox.clientLeft); 36 console.log(oBox.clientWidth); 37 console.log(oBox.clientHeight); 38 39 </script> 40 41 </html> 42 43 2.屏幕的可视区域 44 45 <!DOCTYPE html> 46 <html> 47 <head> 48 <meta charset="UTF-8"> 49 <title></title> 50 </head> 51 <body> 52 </body> 53 <script type="text/javascript"> 54 55 // 屏幕的可视区域 56 window.onload = function(){ 57 58 // document.documentElement 获取的是html标签 59 console.log(document.documentElement.clientWidth); 60 console.log(document.documentElement.clientHeight); 61 // 窗口大小发生变化时,会调用此方法 62 window.onresize = function(){ 63 console.log(document.documentElement.clientWidth); 64 console.log(document.documentElement.clientHeight); 65 } 66 67 68 69 } 70 </script> 71 </html> 72 73 3.offset系列 74 代码如下, 75 <!DOCTYPE html> 76 <html> 77 <head> 78 <meta charset="UTF-8"> 79 <title></title> 80 <style type="text/css"> 81 *{ 82 padding: 0; 83 margin: 0; 84 } 85 </style> 86 87 </head> 88 <body style="height: 2000px"> 89 <div> 90 <div class="wrap" style=" width: 300px;height: 300px;background-color: green"> 91 <div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 30px;"> 92 </div> 93 </div> 94 </div> 95 </body> 96 <script type="text/javascript"> 97 window.onload = function(){ 98 var box = document.getElementById('box') 99 /* 100 offsetWidth占位宽 内容+padding+border 101 offsetHeight占位高 102 * offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值 103 * offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值 104 105 * */ 106 console.log(box.offsetTop) 107 console.log(box.offsetLeft) 108 console.log(box.offsetWidth) 109 console.log(box.offsetHeight) 110 111 } 112 113 </script> 114 </html> 115 116 4.scroll系列 117 代码如下: 118 119 <!DOCTYPE html> 120 <html> 121 <head> 122 <meta charset="UTF-8"> 123 <title></title> 124 <style type="text/css"> 125 *{padding: 0;margin: 0;} 126 </style> 127 </head> 128 <body style="width: 2000px;height: 2000px;"> 129 <div style="height: 200px;background-color: red;"></div> 130 <div style="height: 200px;background-color: green;"></div> 131 <div style="height: 200px;background-color: yellow;"></div> 132 <div style="height: 200px;background-color: blue;"></div> 133 <div style="height: 200px;background-color: gray;"></div> 134 <div id = 'scroll' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;"> 135 <p>路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城 136 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城 137 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城 138 路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城路飞学城 139 </p> 140 141 </div> 142 143 144 </body> 145 <script type="text/javascript"> 146 147 window.onload = function(){ 148 149 //实施监听滚动事件 150 window.onscroll = function(){ 151 // console.log(1111) 152 // console.log('上'+document.documentElement.scrollTop) 153 // console.log('左'+document.documentElement.scrollLeft) 154 // console.log('宽'+document.documentElement.scrollWidth) 155 // console.log('高'+document.documentElement.scrollHeight) 156 157 158 } 159 160 var s = document.getElementById('scroll'); 161 162 s.onscroll = function(){ 163 // scrollHeight : 内容的高度+padding 不包含边框 164 console.log('上'+s.scrollTop) 165 console.log('左'+s.scrollLeft) 166 console.log('宽'+s.scrollWidth) 167 console.log('高'+s.scrollHeight) 168 } 169 } 170 171 </script> 172 </html>
8 实例练习
1 搜索框
1 <input id="ID1" type="text" value="请输入用户名" onblur="Blurs()" onfocus="Focus()"> 2 3 4 <script> 5 6 function Focus(){ 7 8 var input=document.getElementById("ID1"); 9 if (input.value=="请输入用户名"){ 10 input.value=""; 11 } 12 13 }; 14 15 function Blurs(){ 16 17 var ele=document.getElementById("ID1"); 18 var val=ele.value; 19 if(!val.trim()){ 20 21 ele.value="请输入用户名"; 22 } 23 } 24 25 </script>
2 模态对话框
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .back{ 8 background-color: rebeccapurple; 9 height: 2000px; 10 } 11 12 .shade{ 13 position: fixed; 14 top: 0; 15 bottom: 0; 16 left:0; 17 right: 0; 18 background-color: coral; 19 opacity: 0.4; 20 } 21 22 .hide{ 23 display: none; 24 } 25 26 .models{ 27 position: fixed; 28 top: 50%; 29 left: 50%; 30 margin-left: -100px; 31 margin-top: -100px; 32 height: 200px; 33 width: 200px; 34 background-color: gold; 35 36 } 37 </style> 38 </head> 39 <body> 40 <div class="back"> 41 <input id="ID1" type="button" value="click" onclick="action('show')"> 42 </div> 43 44 <div class="shade hide"></div> 45 <div class="models hide"> 46 <input id="ID2" type="button" value="cancel" onclick="action('hide')"> 47 </div> 48 49 <script> 50 51 function action(act){ 52 var ele=document.getElementsByClassName("shade")[0]; 53 var ele2=document.getElementsByClassName("models")[0]; 54 if(act=="show"){ 55 ele.classList.remove("hide"); 56 ele2.classList.remove("hide"); 57 }else { 58 ele.classList.add("hide"); 59 ele2.classList.add("hide"); 60 } 61 62 } 63 </script> 64 </body> 65 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>motai</title> 6 <style> 7 #div1{ 8 position:fixed; 9 height:2000px; 10 width:100%; 11 background-color:blue; 12 top:0; 13 left:0; 14 z-index:100; 15 } 16 #div2{ 17 position:fixed; 18 top:0; 19 left:0; 20 right:0; 21 bottom:0; 22 width:100%; 23 background-color:green; 24 z-index:101; 25 opacity:0.3; 26 } 27 #div3{ 28 position:absolute; 29 top:50%; 30 left:50%; 31 margin-left:-100px; 32 margin-top:-100px; 33 height:200px; 34 width:200px; 35 background-color:yellow; 36 z-index:102; 37 } 38 .hide{ 39 display:none; 40 } 41 </style> 42 </head> 43 44 <body> 45 <div id="div1"> 46 <input type="button" value="click" onclick="show()"> 47 </div> 48 <div id="div2" class="div hide"></div> 49 <div id="div3" class="div hide"> 50 <input type="button" value="cancle" onclick="cancle()"> 51 </div> 52 53 <script> 54 function show(){ 55 var ele=document.getElementsByClassName('div'); 56 for (var i=0;i<ele.length;i++){ 57 ele[i].classList.remove('hide'); 58 } 59 } 60 function cancle(){ 61 var ele=document.getElementsByClassName('div'); 62 for (var i=0;i<ele.length;i++){ 63 ele[i].classList.add('hide'); 64 } 65 } 66 </script> 67 </body> 68 </html>
3 全选反选取消
1 <button onclick="select('all');">全选</button> 2 <button onclick="select('cancel');">取消</button> 3 <button onclick="select('reverse');">反选</button> 4 5 <table border="1" id="Table"> 6 <tr> 7 <td><input type="checkbox"></td> 8 <td>111</td> 9 </tr> 10 <tr> 11 <td><input type="checkbox"></td> 12 <td>222</td> 13 </tr> 14 <tr> 15 <td><input type="checkbox"></td> 16 <td>333</td> 17 </tr> 18 <tr> 19 <td><input type="checkbox"></td> 20 <td>444</td> 21 </tr> 22 </table> 23 24 25 <script> 26 function select(choice){ 27 var ele=document.getElementById("Table"); 28 29 var inputs=ele.getElementsByTagName("input"); 30 for (var i=0;i<inputs.length;i=i+1){ 31 32 var ele2=inputs[i]; 33 if (choice=="all"){ 34 ele2.checked=true; 35 36 }else if(choice=="cancel"){ 37 ele2.checked=false; 38 } 39 else { 40 41 if (ele2.checked){ 42 ele2.checked=false; 43 }else { 44 ele2.checked=true; 45 } 46 } 47 48 } 49 } 50 </script>
4 两级联动
1 <select id="province"> 2 <option>请选择省:</option> 3 </select> 4 5 <select id="city"> 6 <option>请选择市:</option> 7 </select> 8 9 10 <script> 11 data={"河北省":["廊坊","邯郸"],"北京":["朝阳区","海淀区"]}; 12 13 14 var p=document.getElementById("province"); 15 var c=document.getElementById("city"); 16 17 for(var i in data){ 18 var option_pro=document.createElement("option"); 19 20 option_pro.innerHTML=i; 21 22 p.appendChild(option_pro); 23 } 24 p.onchange=function(){ 25 26 pro=(this.options[this.selectedIndex]).innerHTML; 27 citys=data[pro]; 28 29 c.options.length=0; 30 31 for (var i in citys){ 32 var option_city=document.createElement("option"); 33 option_city.innerHTML=citys[i]; 34 c.appendChild(option_city); 35 } 36 37 } 38 </script>
5 select左右移
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 #box-l,#choice,#box-r{ 8 display:inline-block; 9 } 10 </style> 11 </head> 12 <body> 13 <div id="box-l"> 14 <select multiple="multiple" size="10" id="left"> 15 <option>book</option> 16 <option>book2</option> 17 <option>book3</option> 18 <option>book4</option> 19 <option>book5</option> 20 <option>book6</option> 21 </select> 22 </div> 23 <div id="choice"> 24 <input class="add" type="button" value="--->" onclick="add()"><br> 25 <input class="remove" type="button" value="<---" onclick="remove();"><br> 26 <input class="add-all" type="button" value="====>" onclick="ADDall()"><br> 27 <input class="remove-all" type="button" value="<===" onclick="remall()"> 28 </div> 29 <div id="box-r"> 30 <select multiple="multiple" size="10" id="right"> 31 <option>book9</option> 32 </select> 33 </div> 34 <script> 35 function add(){ 36 var right=document.getElementById("right"); 37 var options=document.getElementById("left").getElementsByTagName("option"); 38 for (var i=0; i<options.length;i++){ 39 var option=options[i]; 40 if(option.selected==true){ 41 option.selected=false; 42 right.appendChild(option); 43 i--; 44 } 45 } 46 } 47 function ADDall(){ 48 var right=document.getElementById("right"); 49 var options=document.getElementById("left").getElementsByTagName("option"); 50 for (var i=0; i<options.length;i++){ 51 var option=options[i]; 52 right.appendChild(option); 53 i--; 54 } 55 } 56 function remove(){ 57 var left=document.getElementById("left"); 58 var options=document.getElementById("right").getElementsByTagName("option"); 59 for (var i=0; i<options.length;i++){ 60 var option=options[i]; 61 if(option.selected==true){ 62 option.selected=false; 63 left.appendChild(option); 64 i--; 65 } 66 } 67 } 68 function remall(){ 69 var left=document.getElementById("left"); 70 var options=document.getElementById("right").getElementsByTagName("option"); 71 for (var i=0; i<options.length;i++){ 72 var option=options[i]; 73 left.appendChild(option); 74 i--; 75 } 76 } 77 </script> 78 </body> 79 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style type="text/css"> 7 *{ 8 padding: 0; 9 margin: 0; 10 } 11 ul{ 12 list-style: none; 13 } 14 #tab{ 15 width: 480px; 16 margin: 20px auto; 17 border: 1px solid red; 18 } 19 ul{ 20 width: 100%; 21 overflow: hidden; 22 } 23 ul li{ 24 float: left; 25 width: 160px; 26 height: 60px; 27 line-height: 60px; 28 text-align: center; 29 background-color: #cccccc; 30 } 31 32 ul li a{ 33 text-decoration: none; 34 color:black; 35 } 36 li.active{ 37 background-color: red; 38 } 39 p{ 40 display: none; 41 height: 200px; 42 text-align: center; 43 line-height: 200px; 44 background-color: red; 45 } 46 p.active{ 47 display: block; 48 49 } 50 51 </style> 52 </head> 53 <body> 54 <div id="tab"> 55 <ul> 56 <li class="active"> 57 <a href="#">首页</a> 58 </li> 59 <li> 60 <a href="#">新闻</a> 61 </li> 62 <li> 63 <a href="#">图片</a> 64 </li> 65 </ul> 66 <p class="active">首页内容</p> 67 <p>新闻内容</p> 68 <p>图片内容</p> 69 </div> 70 </body> 71 <script type="text/javascript"> 72 73 var olis = document.getElementsByTagName('li'); 74 var oPs = document.getElementsByTagName('p'); 75 76 var i; 77 for(i = 0; i < olis.length; i++){ 78 79 olis[i].index = i; 80 81 olis[i].onclick = function() { 82 83 for(var j = 0; j < olis.length; j++){ 84 olis[j].className = ''; 85 oPs[j].className = '' 86 } 87 this.className = 'active'; 88 oPs[this.index].className = 'active'; 89 } 90 } 91 </script> 92 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style type="text/css"> 7 *{ 8 padding: 0; 9 margin: 0; 10 } 11 ul{ 12 list-style: none; 13 } 14 #tab{ 15 width: 480px; 16 margin: 20px auto; 17 border: 1px solid red; 18 } 19 ul{ 20 width: 100%; 21 overflow: hidden; 22 } 23 ul li{ 24 float: left; 25 width: 160px; 26 height: 60px; 27 line-height: 60px; 28 text-align: center; 29 background-color: #cccccc; 30 } 31 32 ul li a{ 33 text-decoration: none; 34 color:black; 35 } 36 li.active{ 37 background-color: red; 38 } 39 p{ 40 display: none; 41 height: 200px; 42 text-align: center; 43 line-height: 200px; 44 background-color: red; 45 } 46 p.active{ 47 display: block; 48 49 } 50 51 </style> 52 </head> 53 <body> 54 <div id="tab"> 55 <ul> 56 <li class="active"> 57 <a href="#">首页</a> 58 </li> 59 <li> 60 <a href="#">新闻</a> 61 </li> 62 <li> 63 <a href="#">图片</a> 64 </li> 65 </ul> 66 <p class="active">首页内容</p> 67 <p>新闻内容</p> 68 <p>图片内容</p> 69 70 71 </div> 72 </body> 73 <script type="text/javascript"> 74 75 76 //变量提升 77 /* 78 var a 79 console.log(a); 80 a = 2; 81 console.log(a); 82 */ 83 /* 84 var a; 85 console.log(a); 86 { 87 a = 3; 88 console.log(a); 89 } 90 console.log(a); 91 */ 92 /* 93 console.log(a); 94 { 95 //let声明的变量不会存在变量提升,属于局部作用域 96 let a = 3; 97 console.log(a); 98 } 99 console.log(a); 100 */ 101 102 103 104 var olis = document.getElementsByTagName('li'); 105 var oPs = document.getElementsByTagName('p'); 106 107 108 for(let i = 0; i < olis.length; i++){ 109 110 olis[i].onclick = function() { 111 for(let j = 0; j < olis.length; j++){ 112 olis[j].className = ''; 113 oPs[j].className = '' 114 } 115 this.className = 'active'; 116 oPs[i].className = 'active'; 117 } 118 119 } 120 </script> 121 </html>