R·ex / Zeng


音游狗、安全狗、攻城狮、业余设计师、段子手、苦学日语的少年。 MUGer, hacker, developer, amateur UI designer, punster, Japanese learner.

【JS教程第二篇】树型的文档

注意:本文发布于 2289 天前,文章中的一些内容可能已经过时。

本篇需要对HTML文档结构和JavaScript语法有基本了解。

之前写HTML的时候,有没有觉得整个文档结构有点层次感呢?例如,<html>包含了<head><body>,前者包含了<title>,后者可以包含好多东西;一个<div>中可以包含若干个<span>或者<p>,它们之间又有什么先后顺序呢?

事实上,HTML文档就是一棵树。我们来看下面这个HTML文档:

<html>
    <head>
        <title>Test</title>
        <script src="xxx.js"></script>
    </head>
    <body>
        <div id="header">
            <h1>Welcome</h1>
            <span>It's my world!</span>
        </div>
        <div id="content">
            <p>The first paragraph.</p>
            <p>The second paragraph.</p>
        </div>
        <div id="footer">
            <span>Recommended browser: browser with webkit kernel.</span>
        </div>
    </body>
</html>

我们来看一下它对应的树型结构:

HTML DOM

很“简单易懂”吧?

现在请允许我正式向大家介绍树型结构。这个“树”跟自然界的树是不一样的,它有好多被称为“节点”的东西(图中的方框),最上面那个特殊的节点被称作“根”。每个节点会有若干个孩子(被称为“子节点”),也可能没有孩子。孩子是有先后次序的,就是在文档中出现的次序。同级之间的节点被称为“兄弟节点”。当然,孩子是有父节点的。树结构最大的特点就是,一个节点只能有一个父亲。

在上图中:html是根,它有两个孩子分别是head和body,head在文档中先出现;head有两个孩子分别是title和script,同理body有三个孩子,它们都是div,id分别是header、content和footer,其中#header又有两个孩子……head和body互称兄弟,它们有共同的父亲html。其实,html外面还有个最大的节点:document,这个变量可以直接从JS中访问。

那么我们怎样抓到一个特定的节点呢?JS给我们提供了一连串方法:

通过id抓取元素:document.getElementById("id")
通过标签名抓取元素:document.getElementsByTagName("tag_name")
通过类名抓取元素:document.getElementsByClassName("class_name")

其中因为id在一个文档中不能重复,所以第一个方法只会返回一个节点,而后面两个方法会返回一个节点数组(还记得数组嘛?它是一连串元素的有序集合。数组a的第一个元素是a[0])。例如,我们要获取#header、第二个p,分别可以这么写:

document.getElementById("header")
document.getElementsByTagName("p")[1]

下文均假设我们已经有了一个节点a = document.getElementById("header")。

获取/设置a元素标签括起来的内容
通过a.innerHTML这个属性。如果a是【<p>Hello</p>】,那么a.innerHTML就是Hello。

获取/设置a元素的CSS
通过a.style这个对象。
【a.style.x = "y"】相当于给a加了一条【x: y】的CSS规则,例如【a.style.color = "blue"】就是把字体设为蓝色(CSS里应该写成【color: blue】)。

获取a的家属
父亲:a.parentNode
孩子:a.children或a.childNodes(这会生成一个孩子数组)
第一个 / 最后一个孩子:a.firstChild / a.lastChild(其实就是a.childNodes[0]和a.childNodes[ a.childNodes.length - 1 ],数组arr的长度可以用arr.length获得)
作为一个节点,a和document一样,也具有getElementByXXX的方法,可以获取a的所有子孙中符合条件的节点,例如【a.getElementById("b")】。

下文中的"child",格式都是标准的HTML元素,例如<div id="asd">123</div>,或者直接用getElementByXXX方法获得。

给a添加一个孩子
加到最后的位置:a.appendChild("child")
加到最前的位置:a.insertBefore("child")
删除a的一个孩子
调用a.removeChild("child")方法;

JS还可以对用户的行为(称为“事件”)做出响应。假设我们有这么一个元素:

<h1>Mouse over me!</h1>

我们想让鼠标移过该元素时里面的内容改为“Thanks”,可以这么做:

<h1 onmouseover="this.innerHTML='Thanks'">Mouse over me!</h1>

咦,onmouseover?我们又发现了什么奇怪的东西……

从这句话中大概能推测出,这个值是一段JS,当鼠标移过的时候会执行这段JS,JS中的this指的一定是目前这个h1元素。我们还可能会想到,如果要执行的内容太多,我们可以写个函数,然后这句话来调用写好的函数。

确实是这样的。HTML给我们提供了好多类似的属性:

onload:元素加载完成时
onerror:元素加载失败时
onmouseover:鼠标移过元素的瞬间
onmousedown:鼠标点击元素的瞬间
onmouseup:鼠标抬起的时候
onclick:鼠标点按元素并抬起之后,相当于onmousedown + onmouseup
onmousemove:鼠标在元素上滑动时</pre

作业:将本文提到的方法都用一遍……(因为实在想不出什么特别好的能包含这么多用法的例子了)

版权声明:除文章开头有特殊声明的情况外,所有文章均可在遵从 CC BY 4.0 协议的情况下转载。
上一篇: 【JS教程第一篇】语法当先
下一篇: 【教程】用JavaScript控制CSS规则

这是我们共同度过的

第 1765 天