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) - JavaScript 的核心 ECMAScript 描述了该语言的语法和基本对象
- 文档对象模型(DOM, Document Object Model) - 描述了处理网页内容的方法和接口, 整合js, css, html
- 浏览器对象模型(BOM) Broswer Object Model - 描述了与浏览器进行交互的方法和接口, 整合js和浏览器
JavaScript由三部分组成:ECMAScript、BOM以及DOM 1、核心——ECMAScript:提供核心语言功能 2、文档对象模型——DOM:提供访问和操作网页内容的方法和接口 HTML 和 XML 的应用程序接口(API),用来获取或设置文档中标签的属性,和文档有关, DOM关注的是网页本身的内容. 这里的文档指的是网页, 也就是HTML文档. DOM把页面映射成一个多层节点结构。 为什么使用DOM?Netscape和微软在开发DHTML方面各持己见,为避免两强割据,浏览器互不兼容的局面,保持Web跨平台的天性,DOM应运而生。 DOM1级:由DOM Core和DOM HTML两部分组成。DOM Core规定如何映射基于XML的文档结构,DOM HTML在DOM Core的基础上扩展,增加了针对HTML的对象和方法。 DOM2级:在原来DOM的基础上扩充了鼠标和用户界面事件、范围、遍历(迭代DOM文档的方法),且通过对象接口增加了对CSS的支持,DOM1级中的DOM Core也经过扩展开始支持XML命名空间。引入了新模块:DOM Views——定义了跟踪不同文档视图的接口;DOM Events——定义了事件和事件处理的接口;DOM Style——定义了基于CSS为元素应用样式的接口;DOM Traversal and Range——定义了遍历和操作文档树的接口。 DOM3级:引入了以统一方式加载和保存文档的方法——在DOM加载和保存(DOM Load and Save)模块中定义;新增了验证文档的方法——在DOM验证(DOM Validation)模块中定义。对DOM Core进行了扩展,开始支持XML 1.0规范,涉及XML Infoset、XPath和XML Base。 3、浏览器对象模型——BOM:提供与浏览器交互的方法和接口 BOM可以访问和操作浏览器窗口,使用BOM可以控制浏览器显示的页面以外的部分。HTML5致力于把很多BOM功能写入正式规范。 从根本上讲,BOM只处理浏览器窗口和框架,但习惯把所有针对浏览器的JavaScript扩展算作BOM的一部分,包括弹出新浏览器窗口的功能,移动、缩放和关闭浏览器窗口的功能,提供浏览器详细信息的navigator对象,提供浏览器所加载页面的详细信息的location对象,提供用户显示器分辨率详细信息的screen对象,对cookie的支持,像XMLHttpRequest和IE的ActiveXObject这样的自定义对象。 BOM是由navigator、history、screen、location、document五个对象组成的。
Javascript 在开发中绝大多数情况是基于对象(使用对象, 不是创建, 跟面向对象不同)的, 也是面向对象的.

简单地说,ECMAScript 描述了以下内容:
- 语法
- 类型
- 语句
- 关键字
- 保留字
- 运算符
- 对象 (封装 继承 多态) 基于对象的语言, 使用对象.
JavaScript的引入方式
//1. 直接编写 - 可以放在<head>标签里, 但是推荐放在<body>标签尾部 <script> alert('hello yuan') </script> //2. 导入文件 <script src="hello.js"></script>
ECMAScript
变量&数据类型
变量
声明变量时不用声明变量类型, 全都使用var关键字.
var a;
一行可以声明多个变量, 并且可以是不同类型.
var name="charon", age=20, gender="male";
声明变量时可以不用var, 如果不用var那么它是全局变量.
function func1(){ var a = 123; b=456 } func1(); //alert(a); //a是局部变量, 会报错 alert(b); //b是全局变量可以alert出来
变量命名, 首字符只能是字母,下划线,$美元符 三选一,且区分大小写,x与X是两个变量
变量还应遵守以下某条著名的命名规则:
// 变量命名, 首字符只能是字母,下划线,$美元符中的一个, 且区分大小写, x与X是两个变量. Camel 标记法 首字母是小写的, 接下来的字母都以大写字符开头. 例如: var myTestValue = 0, mySecondValue = "hi"; Pascal 标记法 首字母是大写的, 接下来的字母都以大写字符开头. 例如: Var MyTestValue = 0, MySecondValue = "hi"; 匈牙利类型标记法 在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列), 说明该变量的类型. 例如: i表示整数, s表示字符串 Var iMyTestValue = 0, sMySecondValue = "hi";
基础规范
每行结束可以不加分号. 没有分号会以换行符作为每行的结束
注释, 支持多行注释/* */和单行注释//
使用{}来封装代码块
常量和标识符
常量: 直接在程序中出现的数据值
标识符:
- 由不以数字开头的字母、数字、下划线(_)、美元符号($)组成
- 常用于表示函数、变量等的名称
- 例如:_abc,$abc,abc,abc123是标识符,而1abc不是
- JavaScript语言中代表特定含义的词称为保留字,不允许程序再定义为标识符

五种数据类型
在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值.
- 原始值: 存储在栈(stack)中的原始(基本)数据类型数据段,即它们的值直接存储在变量访问的位置.
- 引用值: 存储在堆(heap)中的对象,即存储在变量处的值是一个指针(point),指向存储对象的内存处.
(如果一个值是引用类型的, 那么它的存储空间将从堆中分配. 由于引用值的大小会改变, 所以不能把它放在栈中, 否则会降低变量查寻的速度. 相反, 放在变量的栈空间中的值是该对象存储在堆中的地址. 地址的大小是固定的, 所以把它存储在栈中对变量性能无任何负面影响)
1. 数字类型(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. 字符串(String)
是由Unicode字符、数字、标点符号组成的序列 字符串常量首尾由单引号或双引号括起 JavaScript中没有字符类型 常用特殊字符在字符串中的表达 字符串中部分特殊字符必须加上右划线\ 常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线
String数据类型的使用
- 特殊字符的使用方法和效果
- Unicode的插入方法
var str="\u4f60\u597d\n哈哈哈\"Charon\""; alert(str); 效果: 你好 哈哈哈"Charon"
3. 布尔型(Boolean)
Boolean类型仅有两个值: true和false, 也代表1和0, 实际运算中true=1,false=0 (true==2; 会返回false)
Boolean值主要用于JavaScript的控制语句,例如
if (x==1){
y=y+1;
}else {
y=y-1;
}
4 & 5. Null & Undefined
Undefined 类型只有一个值, 即undefined. 当声明的变量未初始化时, 该变量的默认值是 undefined.
当函数无明确返回值时, 返回的也是值 "undefined";
Null 类型
另一种只有一个值的类型是 Null, 它只有一个专用值 null, 即它的字面量. 值 undefined 实际上是从值 null 派生来的, 因此 ECMAScript 把它们定义为相等的, 即 null==undefined; 会返回true.
尽管这两个值相等,但它们的含义不同. undefined 是声明了变量但未对其初始化时赋予该变量的值, null 则用于表示尚未存在的对象. 如果函数或方法要返回的是对象, 那么找不到该对象时, 返回的通常是 null.
var person=new Person()
var person=null
数据类型转换
JavaScript属于松散类型的程序语言 变量在声明的时候并不需要指定数据类型 变量只有在赋值的时候才会确定数据类型 表达式中包含不同类型数据则在计算过程中会强制进行类别转换
数字 + 字符串:数字转换为字符串
数字 + 布尔值:true转换为1, false转换为0
字符串 + 布尔值:布尔值转换为字符串true或false
var c="10"; alert(typeof (c)); //String c=+c; //类型转换 alert(typeof (c)); //Number
强制类型转换函数
函数parseInt: 强制转换成整数 例如: parseInt("6.12")=6; parseInt("12a")=12; parseInt("a12")=NaN; parseInt("1a2")=1; (NaN: 当字符串转换数字无效时就是NaN, 属于Number类型) // ------ NaN特点: ------- var n=NaN; alert(n>3); //false alert(n<3); //false alert(n==3); //false alert(n==NaN); //false alert(n!=NaN); //true, NaN参与的所有的运算都是false,除了!= // ----------------------- 函数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"
instanceof
typeof只能判断基本的数据类型, 不能判断对象. 所以用instanceof可以判断是否为某个类型的实例对象.
var s = new String("Charon") alert(typeof(s)) //object alert(s instanceof String) //true
运算符
算数运算符
加(+), 减(-), 乘(*), 除(/), 余数(% ) 加、减、乘、除、余数和数学中的运算方法一样 例如:9/2=4.5,4*5=20,9%2=1
-除了可以表示减号还可以表示负号 例如:x = -y
+除了可以表示加法运算还可以用于字符串的连接 例如:"abc"+"def"="abcdef"
递增(++), 递减(--)
i++/++i 都相当于i=i+1, i--/--i 都相当于i=i-1. i++表示先把i的值给表达式, 再做递增; ++i表示先递增, 再把递增后的值给表达式. i--/--i 同理 var i=1; console.log(i++); //1 console.log(++i); //3 console.log(--i); //2 console.log(i--); //2 console.log(i); //1
赋值运算符
简单的赋值运算符由等号(=)实现,只是把等号右边的值赋予等号左边的变量. 配合其他运算符可以简化表达式, 如 var iNum = 10; iNum += 10; 还有 *=, /=, -=....
逻辑运算符(Boolean运算符, 等性运算符, 关系运算符)
等于(==), 不等于(!=), 大于(>), 小于(<), 大于等于(>=), 小于等于(<=) 与 (&&) 、或(||) 、非(!)
1 && 1 = 1 1 || 1 = 1
1 && 0 = 0 1 || 0 = 1
0 && 0 = 0 0 || 0 = 0
!0=1 !1=0
Boolean运算符 - AND ( && )
如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:
- 如果一个运算数是对象,另一个是 Boolean 值,返回该对象。
- 如果两个运算数都是对象,返回第二个对象。
- 如果某个运算数是 null,返回 null。
- 如果某个运算数是 NaN,返回 NaN。
- 如果某个运算数是 undefined,发生错误。
Boolean运算符 - OR ( || ) 支持短路原则, 即前面为false, 不再检查第二个就直接返回false
与逻辑 AND 运算符相似, 如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值.
- 如果一个运算数是对象,并且该对象左边的运算数值均为 false,则返回该对象。
- 如果两个运算数都是对象,返回第一个对象。
- 如果最后一个运算数是 null,并且其他运算数值均为 false,则返回 null。
- 如果最后一个运算数是 NaN,并且其他运算数值均为 false,则返回 NaN。
- 如果某个运算数是 undefined,发生错误。
Boolean运算符 - NOT ( ! )
逻辑 NOT 运算符返回的一定是 Boolean 值
- 如果运算数是对象,返回 false
- 如果运算数是数字 0,返回 true
- 如果运算数是 0 以外的任何数字,返回 false
- 如果运算数是 null,返回 true
- 如果运算数是 NaN,返回 true
- 如果运算数是 undefined,发生错误
等性运算符 - 等号和非等号 (==和!=处理原始值 ===和!==处理对象)
等号(==), 当且仅当两个运算数相等时, 它返回 true. 非等号(!=)反之亦然.
执行类型转换的规则如下:
- 如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
- 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
- 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
- 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
- 值 null 和 undefined 相等。
- 在检查相等性时,不能把 null 和 undefined 转换成其他值。
- 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
- 如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。

等性运算符 -全等号和非全等号
全等号(===)和非全等号(!==), 只有在无需类型转换运算数就相等的情况下, 才返回 true.
var sNum = "66"; var iNum = 66; alert(sNum == iNum); //输出 "true" alert(sNum === iNum); //输出 "false" alert(sNum !== iNum); //输出 "true"
关系运算符
比较运算符两侧如果一个是数字类型, 一个是其他类型, 会将其类型转换成数字类型.
比较运算符两侧如果都是字符串类型, 比较的是最高位的ascii码, 如果最高位相等, 继续取第二位比较.
var bResult = "Blue" < "alpha"; alert(bResult); //输出 true // 字符串 "Blue" 小于 "alpha",因为字母 B 的字符代码是 66,字母 a 的字符代码是 97
var bResult = "25" < "3"; alert(bResult); //输出 "true" // 两个运算数都是字符串, 所以比较的是它们的字符代码("2" 的字符代码是 50, "3" 的字符代码是 51)
var bResult = "25" < 3; alert(bResult); //输出 "false" // 字符串 "25" 将被转换成数字 25,然后与数字 3 进行比较.
var bResult = "a" < 3; alert(bResult); //输出 "false" // 字母 "a" 不能转换成有意义的数字. 如果对它调用 parseInt() 方法,返回的是 NaN. 根据规则,任何包含 NaN 的关系运算符都要返回 false.
控制语句
if 控制语句

if语句嵌套格式 if (表达式1) { 语句1; }else if (表达式2){ 语句2; }else if (表达式3){ 语句3; } else{ 语句4; }
if (x==1){ y="星期一"; }else if (x==2){ y="星期二"; ... }else if (x==6){ y="星期六"; }else if (x==0){ y="星期日"; }else{ 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结构更加简洁清晰, 使程序可读性更强, 效率更高.
首先要看一个问题,if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断;而 switch 只能对基本类型进行数值比较。两者的可比性就仅限在两个基本类型比较的范围内。 说到基本类型的数值比较,那当然要有两个数。然后重点来了—— if 语句每一句都是独立的,看下面的语句: if (a == 1) ... else if (a == 2) ... 这样 a 要被读入寄存器两次,1 和 2 分别被读入寄存器一次。于是你是否发现其实 a 读两次是有点多余的,在你全部比较完之前只需要一次读入寄存器就行了,其余都是额外开销。但是 if 语句必须每次都把里面的两个数从内存拿出来读到寄存器,它不知道你其实比较的是同一个 a。 于是 switch case 就出来了,把上面的改成 switch case 版本: switch (a) { case 0: break; case 1: } 总结: 1.switch用来根据一个整型值进行多路分支,并且编译器可以对多路分支进行优化 2.switch-case只将表达式计算一次,然后将表达式的值与每个case的值比较,进而选 择执行哪一个case的语句块 3.if..else 的判断条件范围较广,每条语句基本上独立的,每次判断时都要条件加载 一次。 所以在多路分支时用switch比if..else if .. else结构要效率高。
for 循环控制语句

for循环基本格式
for (初始化;条件;增量){
语句1;
...
}
for (var i=1;i<7;i++){ document.write("<H"+i+">hello</H "+i+"> "); document.write("<br>"); //效果: 从H1到H6的hello } //---------------------------------------------- var arr=[1,"hello",true] for (var i in arr) { console.log(i) //index console.log(arr[i]) //value }
注意:
<p>Charon</p> <p>Alan</p> <script> doms=document.getElementsByTagName("p"); for (var i in doms){ console.log(i); // 0 1 length item namedItem // console.log(doms[i]) //获取DOM对象和所有属性的值 } //用上面的for循环可以获取一个DOM元素集, 元素集包含了对象的所有属性 //用下面这种for循环可以获取DOM对象 for (var i=0;i<doms.length;i++){ console.log(i) ; // 0 1 // console.log(doms[i]) //获取DOM对象 } </script>
结论:for(var i in xx)不推荐使用.
while 循环控制语句

while循环基本格式
while (条件){
语句1;
...
}
var i=1; while (i<=7) { document.write("<H"+i+">hello</H "+i+"> "); document.write("<br>"); i++; } //循环输出H1到H7的字体大小
异常处理
try { //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 } catch (e) { // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。 //e是一个局部变量,用来指向Error对象或者其他抛出的对象 } finally { //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。 }
注:主动抛出异常 throw Error('xxxx')
ECMA对象
从传统意义上来说, ECMAScript 并不真正具有类. 事实上, 除了说明不存在类, 在 ECMA-262 中根本没有出现"类"这个词. ECMAScript 定义了"对象定义", 逻辑上等价于其他程序设计语言中的类.
var o = new Object();
对象有三种 - 本地对象, 内置对象, 宿主对象:
- 本地对象(native object)就是由ECMAScript定义的类(引用类型).
- 内置对象(built-in object)就是不必明确实例化内置对象, 它已被实例化了. ECMA-262 只定义了两个内置对象, 即 Global 和 Math (它们也是本地对象, 根据定义, 每个内置对象都是本地对象).
- 宿主对象(host object)就是所有非本地对象, 即 BOM 和 DOM 对象都是宿主对象.

object对象:ECMAScript 中的所有对象都由这个对象继承而来;Object 对象中的所有属性和方法都会出现在其他对象中
ToString() : 返回对象的原始字符串表示.
ValueOf() : 返回最适合该对象的原始值. 对于许多对象,该方法返回的值都与 ToString() 的返回值相同.
11种内置对象:

在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String、Math、Array、Date、RegExp都是JavaScript中重要的内置对象,在JavaScript程序大多数功能都是通过对象实现的.
String对象
创建字符串对象
创建方式1: var str="hello world"; // 调用字符串的对象属性或方法时自动创建对象,用完就丢弃. 创建方式2: var str1= new String("hello word"); // 采用new创建字符串对象str, 全局有效.
String对象的属性
获取字符串的长度: length
var str1="String对象"; var str2=""; alert("str1长度 "+str1.length); alert("str2长度 "+str2.length);
String对象的方法


String对象的方法(1) —— 格式编排方法
格式编排方法返回值列表
书写格式: String对象提供了一组针对HTML格式的方法,如x.anchor()返回锚定义字符串<a>x</a>, x.bold()返回粗体表示字符串<b>x</b>,x.sup()返回上标格式字符串<sup>x</sup>. // ----------------------------------------- var x="charon"; var y="x.italics():"+x.italics(); document.write(y.fontsize(10)); //<font size="10">x.italics():<i>charon</i></font>
String对象的方法(2)—— 大小写转换
var str1="AbcdEfgh"; var str2=str1.toLowerCase(); var str3=str1.toUpperCase(); alert(str2); //结果为"abcdefgh" alert(str3); //结果为"ABCDEFGH"
String对象的方法(3) —— 获取指定字符
书写格式: x.charAt(index) x.charCodeAt(index) x代表字符串对象 index代表字符位置 index从0开始编号 charAt返回index位置的字符 charCodeAt返回index位置的Unicode编码 // ---------------------- var str1="Hello World! 凯伦"; var str2=str1.charAt(14); var str3=str1.charCodeAt(14); alert(str2); //结果为"伦" alert(str3); //结果为20262
String对象的方法(4)—— 查询字符串
书写格式: x.indexOf(findstr, index) x.lastIndexOf(findstr) //------------------------------------- var str1="welcome to the world of JS!"; var str2=str1.indexOf("l"); var str3=str1.lastIndexOf("l"); alert(str2); // 结果为2 alert(str3); // 结果为18 //**************************************************** 书写格式: x.match(regexp) x.search(regexp) x代表字符串对象 regexp代表正则表达式或字符串 match返回匹配字符串的数组,如果没有匹配则返回null search返回匹配字符串的首字符位置索引 //------------------------------------- var str1="welcome to the world of JS!"; var str2=str1.match("world"); var str3=str1.search("world"); alert(str2[0]); //结果为"world" alert(str3); //结果为15
String对象的方法(5) ——子字符串处理
截取子字符串
书写格式: x.substr(start, length) x.substring(start, end) x代表字符串对象 start表示开始位置 length表示截取长度 end是结束位置加1 第一个字符位置为0 //------------------------------------- var str1="abcdefgh"; var str2=str1.substr(2,4); var str3=str1.substring(2,4); alert(str2); //结果为"cdef" alert(str3); //结果为"cd" //******************************************************* 书写格式: x.slice(start, end) //------------------------------------- var str1="abcdefgh"; var str2=str1.slice(2,4); var str3=str1.slice(4); var str4=str1.slice(2,-1); var str5=str1.slice(-3,-1); alert(str2); //结果为"cd" alert(str3); //结果为"efgh" alert(str4); //结果为"cdefg" alert(str5); //结果为"fg"
替换子字符串
书写格式: x.replace(findstr,tostr) //------------------------------------- var str1="abcdefgh"; var str2=str1.replace("cd","aaa"); alert(str2); //结果为"abaaaefgh"
分割字符串
书写格式: x.split(str) //------------------------------------- var str1="一,二,三,四,五,六,日"; var strArray=str1.split(","); alert(strArray[1]); //结果为"二"
连接字符串
书写格式: y=x.concat(addstr) x代表字符串对象 addstr为添加字符串 返回x+addstr字符串 //------------------------------------- var str1="abcd"; var str2=str1.concat("efgh"); alert(str2); //结果为"abcdefgh"
Array对象
Array 对象用于在单个的变量中存储多个值.
数组的特性:
- js中的数组可以装任意类型, 没有任何限制.
- js中的数组, 长度是随着下标变化的, 即用到多长就有多长.
创建数组对象
创建方式1: var a=[1,2,3]; 创建方式2: var arr = new Array(); // 创建数组时允许指定元素个数也可以不指定元素个数. var arr1 = new Array(size); // 如果仅一个数字参数, 表示的是数组大小, 而不是其元素 初始化数组对象: var cnweek=new Array(7); cnweek[0]="星期日"; cnweek[1]="星期一"; ... cnweek[6]="星期六"; 也可以直接在建立对象时初始化数组元素, 元素类型允许不同. var test=new Array(100,"a",true);
创建二维数组
var cnweek=new Array(7); for (var i=0;i<=6;i++){ cnweek[i]=new Array(2); } cnweek[0][0]="星期日"; cnweek[0][1]="Sunday"; cnweek[1][0]="星期一"; cnweek[1][1]="Monday"; ... cnweek[6][0]="星期六"; cnweek[6][1]="Saturday";
Array对象的属性
获取数组元素的个数:length
var cnweek=new Array(7); cnweek[0]="星期日"; cnweek[1]="星期一"; cnweek[2]="星期二"; cnweek[3]="星期三"; cnweek[4]="星期四"; cnweek[5]="星期五"; cnweek[6]="星期六"; for (var i=0;i<cnweek.length;i++){ document.write(cnweek[i]+" | "); } document.write(cnweek[7]) //undefined
Array对象的方法

连接数组-join方法
x.join(bystr) x代表数组对象 bystr作为连接数组中元素的字符串 返回连接后的字符串 与字符串的split功能刚好相反 // --------------------------- var arr1=[1, 2, 3, 4, 5, 6, 7]; var str1=arr1.join("-"); alert(str1); //结果为"1-2-3-4-5-6-7"
连接数组-concat方法
x.concat(value,...) // ------------------- var a = [1,2,3]; var a = new Array(1,2,3); var b=a.concat(4,5) ; alert(a.toString()); //返回结果为1,2,3 alert(b.toString()); //返回结果为1,2,3,4,5
数组排序-reverse sort
x.reverse() x.sort() // ----------------------------- var arr1=[32, 12, 111, 444]; //var arr1=["a","d","f","c"]; arr1.reverse(); //颠倒数组元素 alert(arr1.toString()); //结果为444,111,12,32 arr1.sort(); //排序数组元素 alert(arr1.toString()); //结果为111,12,32,444 结果是按每个元素的第一个字符的ascii码的大小来比的 //------------------------------ 按数字大小比较: var arr6=[4,1,6,6,3,100,2]; console.log(arr6.sort(mysort)); //mysort做的是, 如, 比较mysort(4,1)若返回正数,即返回true,就调换位置 //接着mysort(4,6)返回的为负数, 即返回false, 所以不调换位置, 以此类推 function mysort(a,b) { return a-b; // 简便写法 // if (a>b){ // 复杂写法 // return 1; // }else if(a<b){ // return -1; // }else { // return 0 // } }
数组切片-slice
x.slice(start, end) x代表数组对象 start表示开始位置索引 end是结束位置下一数组元素索引编号 第一个数组元素索引为0 start、end可为负数,-1代表最后一个数组元素 end省略则相当于从start位置截取以后所有数组元素 // -------------------------------------- var arr1=['a','b','c','d','e','f','g','h']; var arr2=arr1.slice(2,4); var arr3=arr1.slice(4); var arr4=arr1.slice(2,-1); alert(arr2.toString()); //结果为"c,d" alert(arr3.toString()); //结果为"e,f,g,h" alert(arr4.toString()); //结果为"c,d,e,f,g"
删除子数组
x. splice(start, deleteCount, value, ...) x代表数组对象 splice的主要用途是对数组指定位置进行删除和插入 start表示开始位置索引 deleteCount删除数组元素的个数 value表示在删除位置插入的数组元素 value参数可以省略 // ----------------------------- var a = [1,2,3,4,5,6,7,8]; a.splice(1,2); //a变为 [1,4,5,6,7,8] alert(a.toString()); a.splice(1,1); //a变为[1,5,6,7,8] alert(a.toString()); a.splice(1,0,2,3); //a变为[1,2,3,5,6,7,8] alert(a.toString());
数组的进出栈操作
x.push(value, ...) 压栈 x.pop() 弹栈 x代表数组对象 value可以为字符串、数字、数组等任何值 push是将value值添加到数组x的结尾 pop是将数组x的最后一个元素删除 // --------------------------------- var arr1=[1,2,3]; arr1.push(4,5); alert(arr1); //结果为"1,2,3,4,5" arr1.push([6,7]); alert(arr1) //结果为"1,2,3,4,5,6,7" arr1.pop(); alert(arr1); //结果为"1,2,3,4,5"
数组的进出队列操作
x.unshift(value,...) x.shift() x代表数组对象 value可以为字符串、数字、数组等任何值 unshift是将value值插入到数组x的开始 shift是将数组x的第一个元素删除 // ------------------------------------- var arr1=[1,2,3]; arr1.unshift(4,5); alert(arr1); //结果为"4,5,1,2,3" arr1. unshift([6,7]); alert(arr1); //结果为"6,7,4,5,1,2,3" arr1.shift(); alert(arr1); //结果为"4,5,1,2,3"
Date对象
创建Date对象
//方法1:不指定参数 var nowd1=new Date(); alert(nowd1.toLocaleString( )); //方法2:参数为日期字符串 var nowd2=new Date("2004/3/20 11:12"); alert(nowd2.toLocaleString( )); var nowd3=new Date("04/03/20 11:12"); alert(nowd3.toLocaleString( )); //方法3:参数为毫秒数 var nowd3=new Date(5000); alert(nowd3.toLocaleString( )); alert(nowd3.toUTCString()); //方法4:参数为年月日小时分钟秒毫秒 var nowd4=new Date(2004,2,20,11,12,0,300); alert(nowd4.toLocaleString( )); //毫秒并不直接显示
Date对象的方法 - 获取日期和时间
getDate() 获取日 getDay () 获取星期 getMonth () 获取月(0-11) getFullYear () 获取完整年份 getYear () 获取年 getHours () 获取小时 getMinutes () 获取分钟 getSeconds () 获取秒 getMilliseconds () 获取毫秒 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 // 2018年03月07日 01: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对象的方法 - 设置日期和时间
//setDate(day_of_month) 设置日 //setMonth (month) 设置月 //setFullYear (year) 设置年 //setHours (hour) 设置小时 //setMinutes (minute) 设置分钟 //setSeconds (second) 设置秒 //setMillliseconds (ms) 设置毫秒(0-999) //setTime (allms) 设置累计毫秒(从1970/1/1午夜) var x=new Date(); x.setFullYear (1997); //设置年1997 x.setMonth(7); //设置月7 x.setDate(1); //设置日1 x.setHours(5); //设置小时5 x.setMinutes(12); //设置分钟12 x.setSeconds(54); //设置秒54 x.setMilliseconds(230); //设置毫秒230 document.write(x.toLocaleString( )+"<br>"); //返回1997年8月1日5点12分54秒 x.setTime(870409430000); //设置累计毫秒数 document.write(x.toLocaleString( )+"<br>"); //返回1997年8月1日12点23分50秒
Date对象的方法 - 日期和时间的转换
getTimezoneOffset():8个时区×15度×4分/度=480; 返回本地时间与GMT的时间差,以分钟为单位 toUTCString() 返回国际标准时间字符串 toLocalString() 返回本地格式时间字符串 Date.parse(x) 返回累计毫秒数(从1970/1/1午夜到本地时间) Date.UTC(x) 返回累计毫秒数(从1970/1/1午夜到国际时间)
RegExp对象
在表单验证时使用该对象验证用户填入的字符串是否符合规则.
创建正则对象
var x = new RegExp("正则表达式", "验证/匹配模式") //匹配模式: g - global i - 忽略大小写 也可以写gi 创建用户名要求: 首字母必须是英文, 除了第一位其他只能是英文数字和_. 长度最短不能少于6位, 最长不能超过12位 创建方式1: var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$","g"); // 创建方式2: /填写正则表达式/匹配模式; var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/g;
正则对象的方法 - 验证字符串
测试一个字符串是否符合正则规则. 返回值是true 和false.
var re_obj=new RegExp("\d+","g"); alert(re_obj.test("asdf3245lsdk")) //true
正则对象的方法 - 配合String对象的四个方法
String对象中的四个方法可以与正则结合使用: macth search split replace var str = "hello world"; alert(str.match(/o/g)); //查找字符串中 复合正则的 内容. alert(str.search(/h/g)); // 0 查找字符串中符合正则表达式的内容位置 alert(str.split(/o/g)); // 按照正则表达式对字符串进行切割. 返回数组; alert(str.replace(/o/g, "s")); // hells wsrld 对字符串按照正则进行替换.
Math对象
math对象是内置对象, 所以无需创建即可使用, 在调用时需要打出"Math."前缀.
Math对象的属性和方法
属性: alert(Math.PI); 方法: abs(x) 返回数的绝对值。 exp(x) 返回 e 的指数。 floor(x)对数进行下舍入。 log(x) 返回数的自然对数(底为e)。 max(x,y) 返回 x 和 y 中的最高值。 min(x,y) 返回 x 和 y 中的最低值。 pow(x,y) 返回 x 的 y 次幂。 random() 返回 0 ~ 1 之间的随机数。 round(x) 把数四舍五入为最接近的整数。 sin(x) 返回数的正弦。 sqrt(x) 返回数的平方根。 tan(x) 返回角的正切。
Function对象*
功能说明:
- 可以使用变量、常量或表达式作为函数调用的参数
- 函数由关键字function定义
- 函数名的定义规则与标识符一致,大小写是敏感的
- 返回值必须使用return
Function 类可以表示开发者定义的任何函数.
用Function类直接创建函数
创建方式1: function 函数名 (参数) { 函数体; return 返回值; } 创建方式2: var 函数名 = new Function("参数1" ,"参数n", "function_body"); // ------------方式1-------------- alert(1); function func1(){ alert('hello charon!'); return 8; } ret=func1(); alert(ret) // ------------方式2-------------- var func1=new Function("name","alert(\"hello\"+name);") func1("charon")
注意:js的函数加载执行与python不同,它是整体加载完才会执行,所以执行函数放在函数声明上面或下面都可以
函数属于引用类型, 所以它们也有属性和方法.
Function对象的length属性
属性 length 声明了函数期望的参数个数
alert(func1.length)
Function对象的方法
Function对象也有与所有对象共享的 valueOf() 方法和 toString() 方法. 这两个方法返回的都是函数的源代码, 在调试时尤其有用.
运算符void()作用: 拦截方法的返回值
alert(void(fun1(1,2)))
函数的调用
function func1(a,b){ alert(a+b); } func1(1,2); //3 func1(1,2,3);//3 func1(1); //NaN func1(); //NaN //只要函数名写对即可,参数怎么填都不报错. //-------------------面试题---------------- function a(a,b){ alert(a+b); } var a=1; var b=2; a(a,b) // 出错, 因为函数的名字跟后声明的变量的名字一样, 所以函数被变量覆盖了, 而变量不能加()调用, 所以报错
函数的内置对象arguments
function add(a,b){ console.log(a+b);//3 console.log(arguments.length);//2 console.log(arguments);//[1,2] } add(1,2) // ------------------arguments的用处1 ------------------ function nxAdd(){ var result=0; for (var num in arguments){ result+=arguments[num] } alert(result) } nxAdd(1,2,3,4,5) // ------------------arguments的用处2 ------------------ function f(a,b,c){ if (arguments.length!=3){ throw new Error("function f called with "+arguments.length+" arguments,but it just need 3 arguments") } else { alert("success!") } } f(1,2,3,4,5)
匿名函数(自执行函数)
f=function () { alert(123) }; f(); //------- 等同于 ------- (function () { alert(123) })(); // 参数 (function (a) { alert(a) })(234);
函数的作用域链和闭包
作用域
在Java/C#中, 代码块做为作用域, 例如if, while等控制语句有自己作用域.
在JavaScript/Python中, 函数做为作用域, 例如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
嵌套函数的作用域:
var city = 'beijing'; function func(){ var city = 'shanghai'; function inner(){ var city = 'shenzhen'; console.log(city); } inner(); } func(); //shenzhen
var city = 'beijing'; function Bar(){ console.log(city); } function func(){ var city = 'shanghai'; return Bar; } var ret = func(); ret(); //beijing
闭包(closure):
闭包指的是函数可以使用函数之外定义的变量
var city = 'beijing'; function func(){ var city = "shanghai"; function inner(){ // var city = "langfang"; console.log(city); } return inner; } var ret = func(); ret(); //shanghai
var iBaseNum = 10; function addNum(iNum1, iNum2) { function doAdd() { return iNum1 + iNum2 + iBaseNum; } return doAdd(); } //这里内部函数doAdd()是一个闭包, 因为它将获取外部函数的参数 iNum1 和 iNum2 以及全局变量 iBaseNum 的值. addNum() 的最后一步调用了 doAdd(), 把两个参数和全局变量相加, 并返回它们的和.
作用域链(Scope Chain):
由于JavaScript中的每个函数作为一个作用域, 如果出现函数嵌套函数, 则就会出现作用域链.
xo = 'alex'; function Func(){ var xo = "seven"; function inner(){ var xo = 'alvin'; console.log(xo); } inner(); } Func();
如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量时候就会出现顺序,对于上述实例:
当执行console.log(xo)时, 其寻找顺序为根据作用域链从内到外的优先级寻找, 如果内层没有就逐步向上找, 直到没找到抛出异常.

JavaScript的作用域链执行前已创建
JavaScript的作用域在被执行之前已经创建,日后再去执行时只需要按照作用域链去寻找即可。
示例一:
xo = 'alex'; function Func(){ var xo = "seven"; function inner(){ console.log(xo); } return inner; } var ret = Func(); ret(); // 输出结果: seven
上述代码,在函数被调用之前作用域链已经存在:
- 全局作用域 -> Func函数作用域 -> inner函数作用域
当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。
示例二:
xo = 'alex'; function Func(){ var xo = "eirc"; function inner(){ console.log(xo); } xo = 'seven'; return inner; } var ret = Func(); ret(); // 输出结果: seven
上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:
- 全局作用域 -> Func函数作用域 -> inner函数作用域
不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。
示例三:
xo = 'alex';<br> function Bar(){ console.log(xo); } function Func(){ var xo = "seven"; return Bar; } var ret = Func(); ret(); // 输出结果: alex
上述代码,在函数被执行之前已经创建了两条作用域链:
- 全局作用域 -> Bar函数作用域
- 全局作用域 -> Func函数作用域
当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。
声明提前:
在JavaScript中如果不创建变量,直接去使用,则报错:
console.log(xxoo); // 报错:Uncaught ReferenceError: xxoo is not defined
JavaScript中如果创建值而不赋值,则该值为 undefined,如:
var xxoo; console.log(xxoo); // 输出:undefined
在函数内如果这么写:
function Foo(){ console.log(xo); var xo = 'seven'; } Foo(); // 输出:undefined
上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined
for (var i=1; i<=9; i++) { setTimeout( function timer(){ console.log(i);}, 1000 ) } //结果: 隔1秒后, 打印9次10 for (var i=1; i<=9; i++) { ( function(){ var j = i; setTimeout( function timer(){ console.log(j);}, 1000 )} )(); } //结果: 正常打印0-9, 因为以匿名函数的方式执行
BOM对象
BOM(浏览器对象模型), 可以对浏览器窗口进行访问和操作. 使用 BOM, 开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作.
BOM使 JavaScript 有能力与浏览器"对话".
BOM对象:

window对象
window对象
所有浏览器都支持 window 对象。
概念上讲.一个html文档(或者说浏览器上的一个标签页)对应一个window对象.
功能上讲: 控制浏览器窗口的.
使用上讲: window对象不需要创建对象,直接使用即可.
Window 对象方法
alert() 显示带有一段消息和一个确认按钮的警告框。
confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。
prompt() 显示可提示用户输入的对话框。
open() 打开一个新的浏览器窗口或查找一个已命名的窗口。
close() 关闭浏览器窗口。
setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。
clearInterval() 取消由 setInterval() 设置的 timeout。
setTimeout() 在指定的毫秒数后调用函数或计算表达式。
clearTimeout() 取消由 setTimeout() 方法设置的 timeout。
scrollTo() 把内容滚动到指定的坐标。
<script> acceptInput(); var num = Math.round(Math.random()*100); function acceptInput() { //1.让用户输入(prompt) 并接受 用户输入结果 var userNum = prompt("请输入一个0~100之间的数字!", "0"); //2.将用户输入的值与 随机数进行比较 if (isNaN(+userNum)) { //用户输入的无效(重复1,2步骤) alert("请输入有效数字!"); acceptInput(); } else if (userNum > num) { //大了==> 提示用户大了,让用户重新输入(重复2,3步骤) alert("您输入的大了!"); acceptInput(); } else if (userNum < num) { //小了==> 提示用户小了,让用户重新输入(重复2,3步骤) alert("您输入的小了!"); acceptInput(); } else { //答对了==>提示用户答对了 , 询问用户是否继续游戏(confirm). var result = confirm("恭喜您!答对了,是否继续游戏?"); if (result) { //是 ==> 重复123步骤. num = Math.round(Math.random() * 100); acceptInput(); } else { //否==> 关闭窗口(close方法). close(); } } } </script>
setInterval & clearInterval 和 setTimeout & clearTimeout
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="clock" style="width: 249px">
<input type="button" value="begin" onclick="begin_click()">
<input type="button" value="End" onclick="End()">
<input type="button" value="timeout" onclick="f1()">
<script>
function Timeout() {
alert(123);
}
function f1() {
var ID=setTimeout(Timeout,1000);
//clearTimeout(ID) //没反应, 因为在执行前已被清除
}
function begin() {
var stime=getTime();
var ret=document.getElementById("clock");
ret.value=stime;
}
var ID;
function begin_click() {
if (ID==undefined){
begin();
ID=setInterval(begin,1000);
}
}
function End() {
clearInterval(ID);
ID=undefined;
}
// 获取时间
function getTime() {
var date_obj= new Date();
var year=date_obj.getFullYear();
var month=date_obj.getMonth()+1;
var day=date_obj.getDate();
var hour=date_obj.getHours();
var minute=date_obj.getMinutes();
var seconds=date_obj.getSeconds();
var week=date_obj.getDay();
return year+"年"+month+"月"+f(day)+"日"+" "+hour+": "+minute+" :"+seconds+" "+num_week(week)
}
function f(num) {
if (num<10){
return "0"+num;
}
return num;
}
function num_week(n) {
week = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
return week[n]
}
</script>
</body>
</html>
History 对象
History 对象属性
History 对象包含用户(在浏览器窗口中)访问过的 URL。
History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问
属性 length: 返回浏览器历史列表中的 URL 数量
History 对象方法
back() // 加载 history 列表中的前一个 URL。 forward() // 加载 history 列表中的下一个 URL。 go() // 加载 history 列表中的某个具体页面。
<a href="rrr.html">click</a> <button onclick=" history.forward()">>>></button> <button onclick="history.back()">back</button> <button onclick="history.go(-1)">back</button>
Location 对象
Location 对象包含有关当前 URL 的信息.
Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问.
Location 对象方法
location.assign(URL) location.reload() location.replace(newURL)//注意与assign的区别
<input type="button" value="重载" onclick="location.reload()"> <input type="button" value="重载" onclick="location.href='http://www.baidu.com'">
DOM对象
DOM(Document Object Model)定义了访问HTML和XML文档的标准.
DOM是中立于平台和语言的接口, 它允许程序和脚本动态地访问和更新文档的内容, 结构和样式.
DOM 标准被分为3个不同的部分:
- 核心 DOM - 针对任何结构化文档的标准模型
- XML DOM - 针对 XML 文档的标准模型, 定义了所有 XML 元素的对象和属性, 以及访问它们的方法
- HTML DOM - 针对 HTML 文档的标准模型, 定义了所有 HTML 元素的对象和属性, 以及访问它们的方法
HTML DOM就是关于如何获取, 修改, 添加或删除HTML元素的标准.
DOM节点
在HTML DOM中, 所有事物都是节点. DOM 是被视为节点树的 HTML.

HTML 文档中的所有内容都是节点(NODE):
- 整个文档是一个文档节点(document对象)
- 每个 HTML 元素是元素节点(element 对象)
- HTML 元素内的文本是文本节点(text对象)
- 每个 HTML 属性是属性节点(attribute对象)
- 注释是注释节点(comment对象)
节点树中的节点彼此拥有层级关系:
父(parent), 子(child)和同胞(sibling)等术语用于描述这些关系. 父节点拥有子节点, 同级的子节点被称为兄弟节点.
- 在节点树中, 顶端节点被称为根(root)
- 每个节点都有父节点, 除了根之外
- 一个节点可拥有任意数量的子节点
- 兄弟节点是拥有相同父节点的节点

DOM属性
DOM树是为了展示文档中各个对象之间的关系, 用于对象的导航.

节点(自身)属性:
- attributes - 节点(元素)的属性节点
- nodeType - 节点类型
- nodeValue - 节点值
- nodeName - 节点名称
- innerHTML - 节点(元素)的文本值
导航属性:
- parentNode - 节点(元素)的父节点
- firstChild - 节点下第一个子元素
- lastChild - 节点下最后一个子元素
- childNodes - 节点(元素)的子节点
推荐的导航属性:
- parentElement - 父节点标签元素
- children - 所有子标签
- firstElementChild - 第一个子标签元素
- lastElementChild - 最后一个子标签元素
- nextElementtSibling - 下一个兄弟标签元素
- previousElementSibling - 上一个兄弟标签元素
<script>
var ele=document.getElementById("div1");
//firstchild
var ele2=ele.firstChild;
alert(ele2.nodeName); //#text, 它的firstchild是div之后的文本
//lastchild
var ele3=ele.lastChild;
alert(ele3.nodeName); //#text
//childNodes
var ele3=ele.childNodes;
alert(ele3.length); //5
//parentNode
var ele3=ele.parentNode;
alert(ele3.nodeName); //BODY
console.log(ele.nodeName); //DIV
console.log(ele.nodeType); //1
console.log(ele.nodeValue); //null
//--------------- 推荐方式 ------------------------
var ele=document.getElementById("div1");
//firstElementChild
var ele_son=ele.firstElementChild;
alert(ele_son.nodeName) //DIV
//lastElementChild
var ele_son=ele.lastElementChild;
alert(ele_son.nodeName); //P
//children
var ele_sons=ele.children;
alert(ele_sons.length); //2
//parentElement
var ele_son = ele.parentElement;
alert(ele_son.nodeName); //BODY
alert(ele_sons[0]); //[object HTMLDivElement]
for (var i=0;i<ele_sons.length;i++){
console.log(ele_sons[i])
}
var ele=document.getElementById("div1").firstElementChild;
var sib=ele.nextElementSibling;
alert(sib.nodeName); //P
//这些属性都是为了对文档树进行导航;
</script>
DOM访问
访问HTML元素等同于访问节点, 能以不同的方式来访问HTML元素:
全局查找 - 查找整个页面的元素:
- 通过使用 getElementById() 方法
- 通过使用 getElementsByTagName() 方法
- 通过使用 getElementsByClassName() 方法
- 通过使用 getElementsByName() 方法
局部查找 - 查找子节点下的元素:
- 通过使用 getElementsByTagName() 方法
- 通过使用 getElementsByClassName() 方法
<div id="div1">hello <div class="div2">hello 2</div> <div class="div3" name="alan">hello 3 <p >hello inner</p> <p id="ppp">hello inner2</p> <p class="ppp">hello inner3</p> <p name="alex">hello inner4</p> </div> <p>hello p</p> </div> <script> //--------- 全局查找 ------------- //通过ID var temp=document.getElementById("div1"); //通过class var ele=document.getElementsByClassName("div2")[0]; var ele2=ele.nextElementSibling; alert(ele2.innerHTML); //通过tag var tag=document.getElementsByTagName("p"); alert(tag[0].innerHTML) //通过Name //--------- 局部查找 ------------- var ele=document.getElementsByClassName("div3")[0]; //局部查找可以通过 TagName var ele2=ele.getElementsByTagName("p"); alert(ele2.innerHTML) alert(ele2.length) //局部查找可以通过 class var ele4=ele.getElementsByClassName("ppp"); alert(ele4); //局部查找不可以通过 Name var ele5=ele.getElementsByName("alex"); alert(ele5); //局部查找不可以通过ID, 因为ID是全局唯一, 无需在局部查找 var ele3 =ele.getElementById("ppp"); alert(ele3.innerHTML); </script>
注意:
<p>Charon</p> <p>Alan</p> <script> doms=document.getElementsByTagName("p"); for (var i in doms){ console.log(i); // 0 1 length item namedItem // console.log(doms[i]) //获取DOM对象和所有属性的值 } //用上面的for循环可以获取一个DOM元素集, 元素集包含了对象的所有属性 //用下面这种for循环可以获取DOM对象 for (var i=0;i<doms.length;i++){ console.log(i) ; // 0 1 // console.log(doms[i]) //获取DOM对象 } </script>
DOM Event(事件)
DOM允许JavaScript对HTML事件作出反应, 即HTML事件可以触发浏览器中的动作(action). 下面是一个属性列表, 这些属性可插入 HTML 标签来定义事件动作.
onclick 当用户点击某个对象时调用的事件句柄 ondblclick 当用户双击某个对象时调用的事件句柄 onfocus 元素获得焦点 应用场景: 输入框 onblur 元素失去焦点 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证. onchange 域的内容被改变 应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动) onkeydown 某个键盘按键被按下 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交. onkeypress 某个键盘按键被按下并松开 onkeyup 某个键盘按键被松开 onload 一张页面或一幅图像完成加载 onmousedown 鼠标按钮被按下 onmousemove 鼠标被移动 onmouseout 鼠标从某元素移开 onmouseover 鼠标移到某元素之上
onmouseleave 鼠标从元素离 onselect 文本被选中 onsubmit 确认按钮被点击
绑定事件的两种方式(为元素附加事件属性):
<div id="div1" onclick="func1()">hello div <p class="ppp">hello p</p> //事件传播, 点击hello p会alert哈哈再alert不要 </div> <script> var obj=document.getElementsByClassName("ppp")[0]; obj.onclick=function () { alert("哈哈"); } function func1(){ alert("不要") } </script>
注意1: this & self, void
<div id="abc" onclick="func1(this)">事件绑定方式1</div>
<div id="id123">事件绑定方式2</div>
<script>
function func1(self){
console.log(self.id)
}
//------------------------------------------
var ele=document.getElementById("id123").onclick=function(){
console.log(this.id);
}
</script>
<div>haha <div>heihei <!--this: 当前触发的标签对象--> <div onclick="show(this)" ha="123" id="id1">click</div> <div onclick="show(this)" ha="456">click</div> <div onclick="show(this)" ha="163">click</div> <div onclick="show(this)" ha="132">click</div> <div onclick="show(this)" ha="752">click</div> <p>lala</p> </div> </div> <!--void()使函数不能返回有效值(清除所有返回值)--> <a href="javascript:void(0)">不跳转</a> <a href="#">跳转</a> <a href="javascript:ale()">函数</a> <a href="javascript:void(window.open('about:blank'))">Click me</a> <script> function show(aa) { console.log(aa.getAttribute("ha")) console.log(aa.getAttribute("id")) } function ale() { alert("charon") } </script>
注意2: 事件传播
<div id="abc_1" style="border:1px solid red;width:300px;height:300px;">
<div id="abc_2" style="border:1px solid red;width:200px;height:200px;"></div>
</div>
<script type="text/javascript">
document.getElementById("abc_1").onclick=function(){
alert('111');
}
document.getElementById("abc_2").onclick=function(event){
alert('222');
event.stopPropagation(); //阻止事件向外层div传播.
}
</script>
onload:
onload 属性只会给body元素加.
这个属性的触发标志着页面内容被加载完成.
应用场景: 页面加载完立刻执行,那么可以使用该事件属性.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// window.onload=function(){
// var ele=document.getElementById("ppp");
// ele.onclick=function(){
// alert(123)
// };
// };
function fun1() {
var ele=document.getElementById("ppp");
ele.onclick=function(){
alert(123)
};
}
</script>
</head>
<body onload="fun1()">
<p id="ppp">hello p</p>
</body>
</html>
onsubmit:
是当表单在提交时触发. 该属性也只会给form元素使用.
应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.
<form id="form">
<input type="text"/>
<input type="submit" value="点我!" />
</form>
<script type="text/javascript">
//阻止表单提交方式1().
//onsubmit 命名的事件函数,可以接受返回值. 其中返回false表示拦截表单提交.其他为放行.
var ele=document.getElementById("form");
ele.onsubmit=function(event) {
// alert("验证失败 表单不会提交!");
// return false;
// 阻止表单提交方式2 event.preventDefault(); ==>通知浏览器不要执行与事件关联的默认动作。
alert("验证失败 表单不会提交!");
event.preventDefault();
}
onchange:
当内容发生变化时触发.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<select onchange="fun3()">
<option>上海</option>
<option>北京</option>
<option>河北</option>
</select>
<script>
function fun3() {
alert(1234);
}
</script>
</body>
</html>
onkeypress & keycode
获取用户按下的键
<p style="width: 500px;height: 200px;background-color: cyan;" id="showZone"></p> <script> document.onkeydown=function(event){ var event=event||window.event; document.getElementById("showZone").innerHTML=event.keyCode; } </script>
判断是否为回车键
<input id="chatMsg" name="chatMsg" type="text" size="90" onkeypress="enterHandler(event);"/>
<script>
function enterHandler(event) {
//获取用户单击键盘的“键值”
var keyCode = event.keyCode ? event.keyCode : event.which;
//如果是回车键
if (keyCode == 13) {
alert("hit enter")
}
}
</script>
DOM操作 (操作, 查)
查:
1. 直接查找
document.getElementById // 根据ID获取一个标签 document.getElementsByName // 根据name属性获取标签集合 document.getElementsByClassName // 根据class属性获取标签集合 document.getElementsByTagName // 根据标签名获取标签集合
2. 间接查找
parentNode // 父节点 childNodes // 所有子节点 firstChild // 第一个子节点 lastChild // 最后一个子节点 nextSibling // 下一个兄弟节点 previousSibling // 上一个兄弟节点 parentElement // 父节点标签元素 children // 所有子标签 firstElementChild // 第一个子标签元素 lastElementChild // 最后一个子标签元素 nextElementtSibling // 下一个兄弟标签元素 previousElementSibling // 上一个兄弟标签元素
操作:
1. HTML内容操作
改变元素内容的最简答的方法是使用 innerHTML, innerText.
2. HTML属性操作
setAttribute(key,value) // 设置标签属性 getAttribute(key) // 获取指定标签属性 var atr = document.createAttribute("class"); atr.nodeValue="democlass"; document.getElementById('n1').setAttributeNode(atr);
3. CSS样式操作
var obj = document.getElementById('i1') obj.style.fontSize = "32px"; obj.style.backgroundColor = "red";
4. HTML标签操作
a. 创建
var tag = document.createElement('a'); tag.innerText = "charon"; tag.className = "c1"; tag.href = "http://www.baidu.com"; xxx.appendChild(tag);
b. 删除
获得要删除的元素
获得它的父元素
使用removeChild();方法删除
<script type="text/javascript"> //在第一个div中动态增加一个a标签. 该a标签点击之后跳转到百度首页. function addNode(){ //1.获得 第一个div var div = document.getElementById("div_1"); //2.创建a标签 createElement==>创建一个a标签 <a></a> var eleA = document.createElement("a"); //3.为a标签添加属性 <a href="http://www.baidu.com"></a> eleA.setAttribute("href", "http://www.baidu.com"); //4.为a标签添加内容 <a href="http://www.baidu.com">百度</a> eleA.innerHTML = "百度"; //5.将a标签添加到div中 div.appendChild(eleA); } //点击后 删除div区域2 function deleteNode(){ //1 获得要删除的div区域 var div = document.getElementById("div_2"); //2.获得父亲 var parent = div.parentNode; //3 由父亲操刀 parent.removeChild(div); } //点击后 替换div区域3 为一个美女 function updateNode(){ //1 获得要替换的div区域3 var div = document.getElementById("div_3"); //2创建img标签对象 <img /> var img = document.createElement("img"); //3添加属性 <img src="001.jpg" /> img.setAttribute("src", "001.JPG"); //4.获得父节点 var parent = div.parentNode; //5.替换 parent.replaceChild(img, div); } //点击后 将div区域4 克隆一份 添加到页面底部 function copyNode(){ //1.获取要克隆的div var div = document.getElementById("div_4"); //2.克隆 参数为true 那么克隆时克隆所有子元素. false 只克隆自己 var div_copy = div.cloneNode(true); //3.获得父亲 var parent = div.parentNode; //4.添加 parent.appendChild(div_copy); } </script>
5. Class操作
className // 获取所有类名 classList.remove(cls) // 删除指定类 classList.add(cls) // 添加类
6. 位置操作
document.documentElement.offsetHeight // 总文档高度 document.documentElement.clientHeight // 当前文档占屏幕高度 tag.offsetHeight // 自身高度 tag.offsetTop // 距离上级定位高度 tag.offsetParent // 父定位标签 tag.scrollTop // 滚动高度 /* clientHeight -> 可见区域:height + padding clientTop -> border高度 offsetHeight -> 可见区域:height + padding + border offsetTop -> 上级定位标签的高度 scrollHeight -> 全文高:height + padding scrollTop -> 滚动高度 特别的: document.documentElement代指文档根节点 */
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body style="margin: 0;">
<div style="height: 900px;">
</div>
<div style="padding: 10px;">
<div id="i1" style="height:190px;padding: 2px;border: 1px solid red;margin: 8px;">
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
</div>
</div>
<script>
var i1 = document.getElementById('i1');
console.log(i1.clientHeight); // 可见区域:height + padding
console.log(i1.clientTop); // border高度
console.log('=====');
console.log(i1.offsetHeight); // 可见区域:height + padding + border
console.log(i1.offsetTop); // 上级定位标签的高度
console.log('=====');
console.log(i1.scrollHeight); //全文高:height + padding
console.log(i1.scrollTop); // 滚动高度
console.log('=====');
</script>
</body>
</html>
7. 提交表单
document.geElementById('form').submit()
实例练习
0. title部分跑马灯
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' >
<title>欢迎blue shit莅临指导 </title>
<script type='text/javascript'>
function Go(){
var content = document.title;
var firstChar = content.charAt(0)
var sub = content.substring(1,content.length)
document.title = sub + firstChar;
}
setInterval('Go()',1000);
</script>
</head>
<body>
</body>
</html>
1. 输入框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input id="ID1" type="text" value="请输入用户名" onblur="Blurs()" onfocus="Focus()">
<script>
function Focus(){
var input=document.getElementById("ID1");
// if (input.value=="请输入用户名"){
// input.value="";
// }
input.value="";
}
function Blurs(){
var ele=document.getElementById("ID1");
var val=ele.value;
if(!val.trim()){
ele.value="请输入用户名";
}
}
</script>
</body>
</html>
2. 弹出框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
}
#div1{
position: fixed;
width: 100%;
top: 0;
left: 0;
height: 2000px;
background-color: #b4b4b4;
z-index: 1000;
}
#div2{
position: fixed;
width: 100%;
z-index: 1001;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: red;
opacity: 0.1;
}
#div3{
height: 200px;
width: 200px;
background-color: blueviolet;
position: absolute;
top: 50%;
left: 50%;
z-index: 1002;
margin-left: -100px;
margin-top: -100px;
}
.hide{
display: none;
}
</style>
</head>
<body>
<div id="div1" >
<input type="button" value="click" onclick="show()">
</div>
<div id="div2" class="div hide"></div>
<div id="div3" class="div hide">
<input type="button" value="cancel" onclick="cancel()">
</div>
<script>
function show() {
var ele=document.getElementsByClassName("div")
for (var i=0;i<ele.length;i++){
ele[i].classList.remove("hide")
}
}
function cancel() {
var ele=document.getElementsByClassName("div")
for (var i=0;i<ele.length;i++){
ele[i].classList.add("hide")
}
}
</script>
</body>
</html>
3. 正反选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button onclick="select('all');">全选</button>
<button onclick="select('cancel');">取消</button>
<button onclick="select('reverse');">反选</button>
<table border="1" id="Table">
<tr>
<td><input type="checkbox"></td>
<td>111</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>222</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>333</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>444</td>
</tr>
</table>
<script>
function select(choice){
var ele=document.getElementById("Table");
var inputs=ele.getElementsByTagName("input");
for (var i=0;i<inputs.length;i=i+1){
var ele2=inputs[i];
if (choice=="all"){
ele2.checked=true;
}else if(choice=="cancel"){
ele2.checked=false;
}
else {
if (ele2.checked){
ele2.checked=false;
}else {
ele2.checked=true;
}
}
}
}
</script>
</body>
</html>
4. 选择框二级联动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<select name="province" id="province" onchange="func1(this)"></select>
<select name="city" id="city" onchange=""></select>
<script>
data = {"福建":["厦门","泉州"],"北京":["朝阳","海淀"],"香港":["九龙","新界"],"深圳":["罗湖","福田"]};
var pro = document.getElementById("province");
for(var i in data){ // for i in key
var option_pro = document.createElement("option");
option_pro.innerHTML= i;
pro.appendChild(option_pro);
}
function func1(self) {
var choice = self.options[self.selectedIndex].innerHTML; //self.options => 获取所有键,返回一个数组
// self.selectedIndex => 返回当前键的index
// 清空上次选的键的值,方式一
city.options.length = 0;
// 清空上次选的键的值,方式二
// for(var k=0; k<city.options.length; k++){
// city.removeChild(city.options[k--]); // 因为当remove第一个child, 下个child自动变成第一个, 故需k--. 即每次remove的都是city.options[0]
// }
for (var i in data[choice]){ // for i in value
var option_city = document.createElement("option");
option_city.innerHTML = data[choice][i];
city.appendChild(option_city);
}
}
</script>
</body>
</html>
5. 选择框左右移动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#box_L,#choice,#box_R{
display: inline-block;
}
</style>
</head>
<body>
<div id="box_L">
<select multiple="multiple" size="10" id="left">
<option>book1</option>
<option>book2</option>
<option>book3</option>
<option>book4</option>
<option>book5</option>
<option>book6</option>
</select>
</div>
<div id="choice">
<input class="add" type="button" value="--->" onclick="add()"><br>
<input class="remove" type="button" value="<---" onclick="remove();"><br>
<input class="add-all" type="button" value="===>" onclick="addall()"><br>
<input class="remove-all" type="button" value="<===" onclick="removeall()">
</div>
<div id="box_R">
<select multiple="multiple" size="10" id="right">
<option>book9</option>
</select>
</div>
<script>
var right = document.getElementById("right");
var left = document.getElementById("left");
function add(){
// var options=document.getElementById("left").getElementsByTagName("option");
var options = left.children;
for (var i=0; i<options.length;i++){
if(options[i].selected == true){
options[i].selected=false;
right.appendChild(options[i]);
i--;
}
}
}
function addall(){
// var options=document.getElementById("left").getElementsByTagName("option");
var options = left.children;
for (var i=0; i<options.length;i++){
var option=options[i];
right.appendChild(option);
i--;
}
}
function remove(){
// var options=document.getElementById("left").getElementsByTagName("option");
var options = right.children;
for (var i=0; i<options.length;i++){
if(options[i].selected == true){
options[i].selected=false;
left.appendChild(options[i]);
i--;
}
}
}
function removeall(){
// var options=document.getElementById("left").getElementsByTagName("option");
var options = right.children;
for (var i=0; i<options.length;i++){
var option=options[i];
left.appendChild(option);
i--;
}
}
</script>
</body>
</html>
6. 滚动高度
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<style>
body{
margin: 0px;
}
img {
border: 0;
}
ul{
padding: 0;
margin: 0;
list-style: none;
}
h1{
padding: 0;
margin: 0;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.wrap{
width: 980px;
margin: 0 auto;
}
.pg-header{
background-color: #303a40;
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,.2);
-moz-box-shadow: 0 2px 5px rgba(0,0,0,.2);
box-shadow: 0 2px 5px rgba(0,0,0,.2);
}
.pg-header .logo{
float: left;
padding:5px 10px 5px 0px;
}
.pg-header .logo img{
vertical-align: middle;
width: 110px;
height: 40px;
}
.pg-header .nav{
line-height: 50px;
}
.pg-header .nav ul li{
float: left;
}
.pg-header .nav ul li a{
display: block;
color: #ccc;
padding: 0 20px;
text-decoration: none;
font-size: 14px;
}
.pg-header .nav ul li a:hover{
color: #fff;
background-color: #425a66;
}
.pg-body{
}
.pg-body .catalog{
position: absolute;
top:60px;
width: 200px;
background-color: #fafafa;
bottom: 0px;
}
.pg-body .catalog.fixed{
position: fixed;
top:10px;
}
.pg-body .catalog .catalog-item.active{
color: #fff;
background-color: #425a66;
}
.pg-body .content{
position: absolute;
top:60px;
width: 700px;
margin-left: 210px;
background-color: #fafafa;
overflow: auto;
}
.pg-body .content .section{
height: 900px;
border: 1px solid red;
}
</style>
<body onscroll="ScrollEvent();">
<div class="pg-header">
<div class="wrap clearfix">
<div class="logo">
<a href="#">
<img src="http://core.pc.lietou-static.com/revs/images/common/logo_7012c4a4.pn">
</a>
</div>
<div class="nav">
<ul>
<li>
<a href="#">首页</a>
</li>
<li>
<a href="#">功能一</a>
</li>
<li>
<a href="#">功能二</a>
</li>
</ul>
</div>
</div>
</div>
<div class="pg-body">
<div class="wrap">
<div class="catalog" id="catalog">
<div class="catalog-item" auto-to="function1"><a>第1张</a></div>
<div class="catalog-item" auto-to="function2"><a>第2张</a></div>
<div class="catalog-item" auto-to="function3"><a>第3张</a></div>
</div>
<div class="content" id="content">
<div menu="function1" class="section">
<h1>第一章</h1>
</div>
<div menu="function2" class="section">
<h1>第二章</h1>
</div>
<div menu="function3" class="section" style="height: 200px;">
<h1>第三章</h1>
</div>
</div>
</div>
</div>
<script>
function ScrollEvent(){
var bodyScrollTop = document.body.scrollTop;
if(bodyScrollTop>50){
document.getElementsByClassName('catalog')[0].classList.add('fixed');
}else{
document.getElementsByClassName('catalog')[0].classList.remove('fixed');
}
var content = document.getElementById('content');
var sections = content.children;
for(var i=0;i<sections.length;i++){
var current_section = sections[i];
// 当前标签距离顶部绝对高度
var scOffTop = current_section.offsetTop + 60;
// 当前标签距离顶部,相对高度
var offTop = scOffTop - bodyScrollTop;
// 当前标签高度
var height = current_section.scrollHeight;
if(offTop<0 && -offTop < height){
// 当前标签添加active
// 其他移除 active
// 如果已经到底部,现实第三个菜单
// 文档高度 = 滚动高度 + 视口高度
var a = document.getElementsByClassName('content')[0].offsetHeight + 60;
var b = bodyScrollTop + document.documentElement.clientHeight;
console.log(a+60,b);
if(a == b){
var menus = document.getElementById('catalog').children;
var current_menu = document.getElementById('catalog').lastElementChild;
current_menu.classList.add('active');
for(var j=0;j<menus.length;j++){
if(menus[j] == current_menu){
}else{
menus[j].classList.remove('active');
}
}
}else{
var menus = document.getElementById('catalog').children;
var current_menu = menus[i];
current_menu.classList.add('active');
for(var j=0;j<menus.length;j++){
if(menus[j] == current_menu){
}else{
menus[j].classList.remove('active');
}
}
}
break;
}
}
}
</script>
</body>
</html>

浙公网安备 33010602011771号