1. 相关概念
由 W3C 批准并由所有于标准相兼容的 Web 浏览器支持的第三方技术成为 DOM (文档对象模型)。可以利用 DOM 改善文档的可交互性,就像利用 CSS 给文档添加各种样式一样。
JS:是一种脚本语言,JS 脚本通常只能通过 Web 浏览器去完成某种操作而不是独立运行。JS 提供了一种操控 Web 浏览器的手段,例如,JS 语言可以用来调整浏览器窗口的高度、宽度和屏显位置等属性。以这种办法给 Web 浏览器本身的属性可以看做是 BOM (浏览器对象模型)。
DOM : Document Object Model,文档对象模型。简单的说 DOM 是一套对文档的内容进行抽象和概念化的方法。
JS 早期版本提供了对 Web 文档的某些实际内容(主要是图像和表单)进行查询和操控的手段。JS 语言本身也预先定义了 "images" 和 "forms" 等关键字。—— 这种试验性质的初级 DOM 被称为 “第 0 级 DOM ”( DOM Level 0)。在形成标准之前,常见的用法包括对图像进行链接和显示以及在客户端进行某种形式的数据合法性验证。
-
DHTML( dynamic HTML)
- 利用 HTML 将网页标记为各种元素
- 利用 CSS 设计各有关元素的排版样式并确定它们在窗口中的显示位置
- 利用 JS 实时操控和改变各种有关样式
DOM Level 1:为解决浏览器的不兼容问题而制定的标准化 DOM —— 可以让任何一种程序设计语言对使用任何一种标记语言编写出来的任何文档进行控制
DOM 是一种 API:一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态的对文档的内容、结构和样式进行访问和修改。
2. JS 语法
-
用 JS 编写的代码必须嵌在一份 HTML/XHTML 文档中才能执行。可以通过两种方法做到:
- 将 JS 代码插入到文档
<head>
部分的<script>
间 - 将 JS 代码保存在独立的文件 —— 以
.js
为文件的扩展名,再利用<script>
标签的 src 属性指向该文件
- 将 JS 代码插入到文档
JS 是解释型语言,Web 浏览器将负责完成有关的解释和执行工作。浏览器中的 JS 解释器将直接读如源代码并加以执行。
语句
每条语句的末尾加上一个分号用于分隔
使用
//
作为注释的开头;多行注释使用/* ...... */
;HTML 风格注释<!-
在 JS 中仅适用于单行注释,对于->
HTML 必须使用其来结束注释,但 JS 不要求,它会把其视为注释内容的一部分(建议不使用这种注释)变量
建议在对变量赋值之前进行声明:
var mood, age;
或声明和赋值同时进行:
var mood = "happy", age = 33;
JS 中变量和其他语法元素的名字区分大小写,不允许变量名包含空格或标点符号(
$
例外)数据类型
字符串:由零个或多个字符构成,字符包括字母、数字、标点符号和空格。字符串必须放在引号中——单双引号均可。
\
表示转义符数值:数值可以是任意位数,整数、浮点数,负数
布尔值:
true
或false
。字符串、数值和布尔值都属于离散值 —— 在任意时刻只能有一个值。
数组
数组是由名字相同的多个值构成的一个集合, 集合中的每个值都是这个数组的元素。
使用
Array
声明,声明时可以对数组的元素个数进行限定:var beatles = Array(4);
(并非必须)数组中元素存放位置使用下标
index
给出:array[index] = element;
下标从 0 开始向数组中添加元素:
beatles[0] = 'John';
数组中的元素可以是任意数据类型var beatles = Array("John", "Paul", "George", "Ringo");
<==>var beatles = ["John", "Paul", "George", "Ringo"];
-
关联数组:为每个元素明确的给出下标的方式来创建关联数组
var lennon = Array();
lennon["name"] = "John";
lennon["year"] = 1940;
lennon["living"] = false;
```
操作
算术操作符:
+
、-
、*
、/
等;++
、--
、+=
条件语句
-
if ... else ... 语句
if(conditon){ statements; }else { statements; }
比较操作符:
>
、<
、>=
、<=
、==
、!=
逻辑操作符:
&&
、||
、!
、!
循环语句
-
while
while(condition){ statements; }
-
do-while:对循环控制条件的求值发生在每次循环结束之后,因此即使循环控制条件的首次求值结果是 false,也会执行一次。
do{ statements; }while(condition);
-
for
for(initial condition; test condition; alter condition){ statements; }
函数
-
函数即一组允许人们在代码里随时调用的语句。从效果上看,每个函数都相当于一个短小的脚本。
function name(arguments){ statements; }
函数可以接受参数来完成指定的数据操作。JS 提供了许多内置函数。
函数可以由返回值,使用
return
函数可以当作是一种数据类型来使用,因此可以把一个函数的调用结果赋值给一个变量
变量的作用域:如果在某个函数中使用了
var
,变量被视为一个局部变量,否则为全局变量 —— 覆盖所有与之同名的变量。对象
-
对象是自我包含的数据集合,包含在对象里的数据可以通过两种形式 —— 属性 和 方法 访问
- 属性是隶属于某个特定对象的变量
- 方法是只有某个特定对象才能调用的函数
-
属性和方法都需要使用
.
来访问。
Object.property
Object.method()
```
- 实例是对象的具体表现形式:对象是统称,实例是个体。为给定对象创建一个新实例需要使用
new
关键字
var jeremy = new Person;
- 可以创建自己的对象 —— 用户定义对象;JS 提供预定义好的对象 —— 内建对象
-
Array
等就是 JS 的内建对象 - 由 Web 浏览器提供的预定义对象被成为宿主对象。主要包括
Form
、Image
和Element
。可以通过这些对象获得关于某给定网页上的表单、图像和各种元素信息。 - 还有一种对象可以获得关于给定网页上的任何一个元素的信息 ——
document
对象
-
3. DOM
DOM: Document Object Model 文档对象模型
当浏览器加载了一个网页后,DOM 根据网页文档创建了一文档对象。
对象是一种独立的数据集合,与对象相关联的变量称为对象的属性,通过对象调用的函数成为对象的方法。在 JS 中对象可以分为三种类型:
- 用户定义对象 user-defined object:由程序员自行创建的对象
- 内建对象 native object:内建在 JS 语言里的对象,如 Array、Math 和 Date 等
- 宿主对象 host object:由浏览器提供的对象
在宿主对象中,window
对象是最基础的对象,其对应着浏览器窗口本身,这个对象的属性和方法统称为 BOM (浏览器对象模型)。相对于 BOM, DOM 主要用来对网页的内容进行处理,而实现这一目标的载体就是 document
对象
DOM 代表着被加载到浏览器窗口里的当前网页。DOM 把一份文档表示为一棵树。
节点
文档是由节点构成的集合,此时的节点代表文档树上的树枝和树叶。有的 DOM 节点还包含其他类型的节点。
-
元素节点
DOM 的原子即为 元素节点 (element node)。这些元素在文档中的布局形成了文档的结构。各种标签提供了元素的名字。元素可以包含其他元素 —— 唯一不会被其他元素包围的元素是 <html> 元素,它是整个节点的根元素
-
文本节点
在 XHTML 中,文本节点总是被包含在元素节点的内部,但并非所有的元素节点都包含由文本节点。
-
属性节点
属性是对元素的具体描述,属性总是被放在起始标签里,所以属性节点总是被包含在元素节点中。并非所有的元素都包含由属性,但所有的属性都被包含在元素中。
-
CSS
CSS 并不属于 DOM,CSS 是告诉浏览器应该如何显示一份文档的内容。类似 DOM,CSS 也把文档的内容视为一颗节点树。节点树上的各元素继承其父元素的样式属性。继承是 CSS 的一项强大的功能,如当为 body 元素定义了一些颜色或字体,包含在 body 元素里的所有元素都将自动获得 —— 也就是继承这些样式。
为了把一个或几个元素与其他元素区别开来,经常需要使用 class 属性或 id 属性
- class 属性
所有的元素都由 class 属性,不同的元素可以有相同的 class 属性值。
- id 属性
id 属性的用途是给网页里的某个元素加上一个独一无二的标识符。每个元素只能由一个 id 属性值,不同的元素必须由不同的 id 属性值。id 属性用于连接文档中的某个元素和 CSS 样式表里的某个样式。
getElementById() 方法
这个方法将返回一个与给定 id 属性值的元素节点相对应的对象。这个方法是与 document 相关联的函数。使用时函数名后边必须根由一对圆括号,包含着函数的参数 —— 即所要获得的那个元素的 id 值,这个 id 值必须放在单引号或双引号中。
document.getElementById('idValue')
这个调用会返回对应 id 值的那个 document 对象。由于 id 值是独一无二的,所以返回的对象也是唯一的。
文档中的每一个元素都对应着一个对象。利用 DOM 提供的方法,可以把这些元素相对应的任何一个对象筛选出来。
一般来说,不需要对文档中的每一个元素都定义一个 id 值,除了使用 id 值外,可以使用其他 DOM 方法来筛选对象。
getElementsByTagName() 方法
getElementByTagName() 方法将返回一个对象数组,每个对象分别对应文档中有给定标签的一个元素。类似 getElementById(),这个方法也只有一个参数 —— 标签的名字。
document.getElementByTagName(tagValue)
与 getElementById() 十分类似,但是 getElementByTagName() 方法返回的是一个对象数组。
getElementByTagName() 方法还允许我们把一个通佩符当作它的参数,这样文档中的所有元素都会被返回。
getAttribute() 方法
当我们定位到特定元素节点后,可以使用 getAttribute() 方法把它的属性值查询出来。这个方法的参数也是一个 —— 需要查询的属性的名字。
object.Attribute(attribute)
getAttribute() 方法不能通过 document 对象调用,必须通过一个元素节点对象来调用。当需要查询的属性不存时则返回 null。
setAttribute() 方法
setAttribute() 方法用于对属性节点的值进行修改。类似于 getAttribute() 方法,必须通过元素节点对象调用的函数,但 setAttribute() 方法需要传递两个参数:
object.setAttribute(attribute, value)
即便要更改的属性并不存在,setAttribute() 也可以首先将属性创建出来,然后对值进行设置。如果属性存在,则直接将原有的值覆盖。
- 通过 setAttribute() 方法对文档做出的修改,将使得文档在浏览器窗口里的显示效果或行为动作发出相应的变化,但查看源代码会发现原来的属性值并没有发生变化。这表明了 DOM 的一个重要特性:先加载文档的静态内容、再以动态的方式对它们进行刷新,动态刷新不影响文档的静态内容。—— 因此 DOM 对页面内容的刷新不需要用户执行刷新操作。
4. 案例研究: JS 美术馆
4.3 JS 函数的调用
-
事件处理函数
事件处理函数的作用是,在预定事件发生时让预先安排好的 JS 代码开始执行,用术语来说就是 “触发一个动作”。例如,如果想在鼠标指针悬停在某个元素上时触发一个动作,就需要使用
onmouseover
事件处理函数;如果想在鼠标指针离开某个元素时触发一个动作,就需要使用onmouseout
事件处理函数。在通过
onclick
事件处理函数去触发的动作时调用showPick()
函数,而要想调用这个函数,就必须向它传递一个参数:一个带有href
属性的元素节点。在图片库的案例中,当把onclick
事件处理函数嵌入到一些链接中时,需要把链接本身用作showPic()
函数的参数,因此可以使用 JS 语言中的this
关键字:表示当前所在的对象。使用事件处理函数调用 JS 代码的语法如下:
event = "JavaScript statement(s);"
JS 代码是包含在一对引号之间的,且可以把任意数量的 JS 语句放在这对引号之间,只要把各条语句用分号隔开即可。
在给某个元素添加了事件处理函数后,一旦发生预定的事件,相应的 JS 代码就会得到执行;那些 JS 代码可以返回一个结果,而这个结果将被传递回那个事件处理函数。比如可以给某个链接添加一个
onclick
事件处理函数,并让这个处理函数所触发的 JS 代码返回布尔值true
或false
。当链接被点击时,如果 JS 返回的结果为true
,onclick
事件处理函数就会认为“这个链接被点击了”;反之,会认为“这个链接没有被点击”。
4.4 对 JS 函数进行功能扩展
- childNodes 属性
childNodes 将文档的节点树中任何一个元素的所有子元素检索出来,childNodes 属性将返回一个数组,这个数组包含给定元素节点的全体子元素:
element.childNodes
使用 childNodes 属性获取文档中的 body 元素的全体子元素:
var body_element = document.getElementsByTagName("body")[0];
body_element.childNodes;
在 JS DOM 中,body 元素还有一个更简单的专用记号:document.body
- nodeType 属性
由 childNode 属性返回的数组包含所有类型的节点 —— 除了所有的元素节点,所有的属性节点和文本节点也包含在其中。文档树的节点类型并非只有元素节点一种,在文档中几乎所有的东西都是一个节点,连空格和换行符都会被解释为节点。这些也都会被包含在 childNode 属性返回的数组当中。
因此需要利用 nodeType 属性来区分文档中的各个节点。nodeType 属性返回一个数字来表示节点的类型,其中经常用到的由三种:
- 1:元素节点
- 2:属性节点
- 3:文本节点
使用 nodeType 的语法如下:
`node.nodeType`
- firstChild 和 lastChild 属性
firstChild 和 lastChild 分别代表 childNodes[ ] 数组的第一个和最后一个元素。
`node.firstChild` <=> `node.childNodes[0]`
`node.lastChild` <=> `node.childNodes[node.childNodes.lenth-1]`
- nodeValue 属性
nodeValue 属性可以检索和设置节点的值:
`node.nodeValue`
如果我们直接 nodeValue 属性检索一个 <p> 对象的值时,得到的并不是包含在这个元素中的文本,而是返回一个 null 值。包含在 <p> 元素里的文本是另一种节点,它在 DOM 里是 <p> 元素的第一个子节点。因此要想得到 <p> 元素的文本内容,就必须检索它的第一个子节点的 nodeValue 属性值。
nodeValue 属性不仅可以用来检索某个节点的值,还可以用它来设置某个节点的值。将需要更改的内容直接赋值给 nodeValue 属性即可改变元素的 nodeValue 属性
`element.firstChild.nodeValue` = text