From 261ea021941f0a901cae6c0a750f800a23d74695 Mon Sep 17 00:00:00 2001
From: wizardforcel <562826179@qq.com>
Date: Fri, 11 May 2018 18:44:09 +0800
Subject: [PATCH] 14.
---
14.md | 155 +++++++++++++++++++++++++++++++++-------------------------
1 file changed, 88 insertions(+), 67 deletions(-)
diff --git a/14.md b/14.md
index b09ed16..98837ca 100644
--- a/14.md
+++ b/14.md
@@ -8,7 +8,7 @@
JavaScript在其沙箱中提供了将文本转换成文档对象模型的功能。它是你可以读取或者修改的数据结构。模型是一个所见即所得的数据结构,改变模型会使得屏幕上的页面产生相应变化。
-### 13.1 文档结构
+## 文档结构
你可以将HTML文件想象成一系列嵌套的箱子。诸如<body>和</body>之类的标签会将其他标签包围起来,而包含在内部的标签也可以包含其他的标签和文本。这里给出上一章中已经介绍过的示例文件。
@@ -35,7 +35,7 @@ JavaScript在其沙箱中提供了将文本转换成文档对象模型的功能
我们可以通过全局绑定document来访问这些对象。该对象的documentElement属性引用了表示<html>标签的对象。由于每个 HTML 文档都有一个头部和一个主体,它还具有`head`和`body`属性,指向这些元素。
-### 13.2 树
+## 树
回想一下第12章中提到的语法树。其结构与浏览器文档的结构极为相似。每个节点可以使用children引用其他节点,而每个子节点又有各自的children。其形状是一种典型的嵌套结构,每个元素可以包含与其自身相似的子元素。
@@ -55,7 +55,7 @@ DOM中也是一样。元素(表示 HTML 标签)的节点用于确定文档
叶子节点是文本节点,而箭头则指出了节点之间的父子关系。
-### 13.3 标准
+## 标准
并非只有JavaScript会使用数字代码来表示节点类型。本章随后将会展示其他的DOM接口,你可能会觉得这些接口有些奇怪。这是因为DOM并不是为JavaScript而设计的,它尝试成为一组语言中立的接口,确保也可用于其他系统中,不只是HTML,还有XML。XML是一种通用数据格式,语法与HTML相近。
@@ -67,7 +67,7 @@ DOM中也是一样。元素(表示 HTML 标签)的节点用于确定文档
但这些问题并非无法改善。因为JavaScript允许我们构建自己的抽象,可以设计改进方式来表达您正在执行的操作。 许多用于浏览器编程的库都附带这些工具。
-### 13.4 通过树结构访问节点
+## 沿着树移动
DOM节点包含了许多指向相邻节点的链接。下面的图表展示了这一点。
@@ -103,7 +103,7 @@ console.log(talksAbout(document.body, "book"));
文本节点的`nodeValue`属性保存它所表示的文本字符串。
-### 13.5 查找元素
+## 查找元素
使用父节点、子节点和兄弟节点之间的连接遍历节点确实非常实用。但是如果我们只想查找文档中的特定节点,那么从document.body开始盲目沿着硬编码的链接路径查找节点并非良策。如果程序通过树结构定位节点,就需要依赖于文档的具体结构,而文档结构随后可能发生变化。另一个复杂的因素是DOM会为不同节点之间的空白字符创建对应的文本节点。例如示例文档中的body标签不止包含3个孩子(<h1>和两个<p>元素),其实包含7个孩子:这三个节点、三个节点前后的空格、以及元素之间的空格。
@@ -130,7 +130,7 @@ console.log(link.href);
第三个类似的方法是getElementsByClassName,它与getElementsByTagName类似,会搜索元素节点的内容并获取所有包含特定class属性的元素。
-### 13.6 修改文档
+## 修改文档
几乎所有DOM数据结构中的元素都可以被修改。文档树的形状可以通过改变父子关系来修改。 节点的`remove`方法将它们从当前父节点中移除。appendChild方法可以添加子节点,并将其放置在子节点列表末尾,而insertBefore则将第一个参数表示的节点插入到第二个参数表示的节点前面。
@@ -149,7 +149,7 @@ console.log(link.href);
replaceChild方法用于将一个子节点替换为另一个子节点。该方法接受两个参数,第一个参数是新节点,第二个参数是待替换的节点。待替换的节点必须是该方法调用者的子节点。这里需要注意,replaceChild和insertBefore都将新节点作为第一个参数。
-### 13.7 创建节点
+## 创建节点
假设我们要编写一个脚本,将文档中的所有图像(``标签)替换为其`alt`属性中的文本,该文本指定了图像的文字替代表示。
@@ -220,7 +220,7 @@ console.log(array.map(s => s.toUpperCase()));
```
-### 13.8 属性
+## 属性
我们可以通过元素的DOM对象的同名属性去访问元素的某些属性,比如链接的href属性。这仅限于最常用的标准属性。
@@ -244,7 +244,7 @@ HTML允许你在节点上设定任何属性。这一特性非常有用,因为
这里有一个常用的属性:class。该属性是JavaScript中的保留字。因为某些历史原因(某些旧版本的JavaScript实现无法处理和关键字或保留字同名的属性),访问class的属性名为className。你也可以使用getAttribute和setAttribute方法,使用其实际名称“class”来访问该属性。
-### 13.9 布局
+## 布局
你可能已经注意到不同类型的元素有不同的布局。某些元素,比如段落(<p>)和标题(<h1>)会占据整个文档的宽度,并且在独立的一行中渲染。这些元素被称为块(Block)元素。其他的元素,比如链接(<a>或<strong>元素则与周围文本在同一行中渲染。这类元素我们称之为内联(Inline)元素。
@@ -303,9 +303,9 @@ getBoundingClientRect方法是获取屏幕中某个元素精确位置的最有
```
-### 13.10 样式
+## 样式
-我们看到了不同的HTML元素会有不同的显示效果。一些元素显示为块,一些则是以内联方式显示。我们还可以添加一些样式,比如使用<strong>加粗内容,或使用<a>使内容变成蓝色,并添加下划线。
+我们看到了不同的HTML元素的绘制是不同的。一些元素显示为块,一些则是以内联方式显示。我们还可以添加一些样式,比如使用<strong>加粗内容,或使用<a>使内容变成蓝色,并添加下划线。
<img>标签显示图片的方式或点击标签<a>时跳转的链接都和元素类型紧密相关。但元素的默认样式,比如文本的颜色、是否有下划线,都是可以改变的。这里给出使用style属性的示例。
@@ -316,7 +316,7 @@ getBoundingClientRect方法是获取屏幕中某个元素精确位置的最有
样式属性可以包含一个或多个声明,格式为属性(比如color)后跟着一个冒号和一个值(比如green)。当包含更多声明时,不同属性之间必须使用分号分隔,比如“color:red;border:none”。
-样式会受到很多因素的影响。例如,display属性控制一个元素是否显示为块元素或内联元素。
+文档的很多方面会受到样式的影响。例如,display属性控制一个元素是否显示为块元素或内联元素。
```html
This text is displayed inline,
@@ -324,17 +324,17 @@ This text is displayed inline,
not at all.
```
-标签block会结束其所在的那一行,因为块元素是不会和周围文本内联显示的。最后一个标签完全不会显示出来,因为display:none会阻止一个元素呈现在屏幕上。这是隐藏元素的一种方式。更好的方式是将其从文档中完全移除,因为随后将其放回去是一件很简单的事情。
+标签block会结束其所在的那一行,因为块元素是不会和周围文本内联显示的。最后一个标签完全不会显示出来,因为display:none会阻止一个元素呈现在屏幕上。这是隐藏元素的一种方式。更好的方式是将其从文档中完全移除,因为稍后将其放回去是一件很简单的事情。
-JavaScript代码可以通过节点的style属性操作元素的样式。该属性保存了一个对象,对象中存储了所有可能的样式属性,这些属性的值是字符串,我们可以把字符串写入属性,修改某些方面的元素样式。
+JavaScript代码可以通过元素的style属性操作元素的样式。该属性保存了一个对象,对象中存储了所有可能的样式属性,这些属性的值是字符串,我们可以把字符串写入属性,修改某些方面的元素样式。
```html
- Pretty text + Nice text
@@ -342,7 +342,7 @@ JavaScript代码可以通过节点的style属性操作元素的样式。该属 一些样式属性名包含破折号,比如font-family。由于这些属性的命名不适合在JavaScript中使用(你必须写成style[“font-family”]),因此在JavaScript中,样式对象中的属性名都移除了破折号,并将破折号之后的字母大写(style.fontFamily)。 -### 13.11 层叠样式 +## 层叠样式 我们把HTML的样式化系统称为CSS,即层叠样式表(Cascading Style Sheets)。样式表是一系列规则,指出如何为文档中元素添加样式。可以在<style>标签中写入CSS。 @@ -356,9 +356,9 @@ JavaScript代码可以通过节点的style属性操作元素的样式。该属Now strong text is italic and gray.
``` -所谓层叠指的是将多条规则组合起来产生元素的最终样式。在上面的示例中,<strong>标签的默认样式font-weight:bold,会被<style>标签中的规则覆盖,并为<strong>标签样式添加font-style和color属性。 +所谓层叠指的是将多条规则组合起来产生元素的最终样式。在示例中,<strong>标签的默认样式font-weight:bold,会被<style>标签中的规则覆盖,并为<strong>标签样式添加font-style和color属性。 -当多条规则重复定义同一属性时,最近的规则会拥有最高的优先级。因此如果<style>标签中的规则包含font-weight:normal,与默认的font-weight规则冲突,那么文本将会显示为普通样式,而非粗体。属性style中的样式会直接作用于节点,而且往往拥有最高优先级。 +当多条规则重复定义同一属性时,最近的规则会拥有最高的优先级。因此如果<style>标签中的规则包含font-weight:normal,违背了默认的font-weight规则,那么文本将会显示为普通样式,而非粗体。属性style中的样式会直接作用于节点,而且往往拥有最高优先级。 我们可以在CSS规则中使用标签名来定位标签。规则.abc指的是所有class属性中包含“abc”的元素。规则#xyz作用于id属性为“xyz”(应当在文档中唯一存在)的元素。 @@ -371,17 +371,17 @@ JavaScript代码可以通过节点的style属性操作元素的样式。该属 background: blue; color: white; } -/* p elements, with classes a and b, and id main */ -p.a.b#main { +/* p elements with id main and with classes a and b */ +p#main.a.b { margin-bottom: 20px; } ``` -优先级规则(偏向于最近定义的规则)只有在规则特殊性相同的情况下有效。规则的特殊性用于衡量该规则描述匹配元素时的准确性。特殊性取决于规则中的元素数量和类型(tag、class或id)。例如,目标规则p.a比目标规则p或.a更具体,因此有更高优先级。 +优先级规则偏向于最近定义的规则,仅在规则特殊性相同时适用。规则的特殊性用于衡量该规则描述匹配元素时的准确性。特殊性取决于规则中的元素数量和类型(tag、class或id)。例如,目标规则p.a比目标规则p或.a更具体,因此有更高优先级。 p>a{….}这种写法将样式作用于<p>标签的直系孩子。类似的,p a{…}应用于所有的<p>标签中的<a>标签,无论是否是直系孩子。 -### 13.12 查询选择器 +## 查询选择器 本书不会使用太多样式表。尽管理解样式表对浏览器程序设计至关重要,想要正确解释所有浏览器支持的属性及其使用方式,可能需要两到三本书才行。 @@ -412,13 +412,13 @@ document对象和元素节点中都定义了querySelectorAll方法,该方法 ``` -与getElementsByTagName这类方法不同,由querySelectorAll返回的对象不是动态变更的。修改文档时其内容不会被修改。 +与`getElementsByTagName`这类方法不同,由`querySelectorAll`返回的对象不是动态变更的。修改文档时其内容不会被修改。但它仍然不是一个真正的数组,所以如果你打算将其看做真的数组,你仍然需要调用`Array.from`。 -querySelector方法(没有All)与querySelectorAll作用相似。如果只想寻找某一个特殊元素,该方法非常有用。该方法只返回第一个匹配元素,如果不存在则返回null。 +querySelector方法(没有All)与querySelectorAll作用相似。如果只想寻找某一个特殊元素,该方法非常有用。该方法只返回第一个匹配的元素,如果没有匹配的元素则返回null。 -### 13.13 位置与动画 +## 位置与动画 -position样式属性是一种强大的布局方法。默认情况下,该属性值为static,表示元素处于文档中的默认位置。若该属性设置为relative,该元素在文档中依然占据空间,但此时其top和left样式属性则是相对于默认位置的偏移。若position设置为absolute,会将元素从默认文档流中移除,该元素将不再占据空间,而会与其他元素重叠。其top和left属性则是相对其最近的封闭元素的偏移,其中position属性的值不是static。如果没有任何封闭元素存在,则是相对于整个文档的偏移。 +position样式属性是一种强大的布局方法。默认情况下,该属性值为static,表示元素处于文档中的默认位置。若该属性设置为relative,该元素在文档中依然占据空间,但此时其top和left样式属性则是相对于常规位置的偏移。若position设置为absolute,会将元素从默认文档流中移除,该元素将不再占据空间,而会与其他元素重叠。其top和left属性则是相对其最近的封闭元素的偏移,其中position属性的值不是static。如果没有任何封闭元素存在,则是相对于整个文档的偏移。 我们可以使用该属性创建一个动画。下面的文档用于显示一幅猫的图片,该图片会沿着椭圆轨迹移动。 @@ -427,59 +427,62 @@ position样式属性是一种强大的布局方法。默认情况下,该属性name | height | -country | +place |
---|---|---|---|
Kilimanjaro | @@ -491,36 +494,39 @@ DOM的组织就像树一样,DOM根据文档结构来层次化地排布元素 <table>标签中,每一行包含一个<tr>标签。<tr>标签内部则是单元格元素,分为表头(<th>)和常规单元格(<td>)。 -我们这里使用第6章中已经使用过的源数据,源数据存储在沙箱的MOUNTAINS绑定中。你也可以从网站上下载([http://eloquentjavascript.net/code/](http://eloquentjavascript.net/code/))数据。 +给定一个山的数据集,一个包含`name`,`height`和`place`属性的对象数组,为枚举对象的表格生成DOM结构。 每个键应该有一列,每个对象有一行,外加一个顶部带有``元素的标题行,列出列名。
-编写一个函数buildTable,调用者指定一个对象数组,数组中每个对象都包含相同的一组属性,该函数根据数组构建出表示表格的DOM结构。表格应该以属性名称作为表头,表头使用<th>元素包围,每一行代表数组中的一个对象,其属性值存放在<td>元素中。
+编写这个程序,以便通过获取数据中第一个对象的属性名称,从对象自动产生列。
-Object.keys函数返回某个对象所有属性名称的数组,读者可能会在程序中用到。
+将所得表格添加到`id`属性为`"mountains"`的元素,以便它在文档中可见。
-当你完成基本功能后,将元素的style.textAlign属性设置为right,将单元格中的数字右对齐。
+当你完成后,将元素的style.textAlign属性设置为right,将包含数值的单元格右对齐。
```html
-
+Mountains+ + ``` -#### 13.15.2 通过标签名获取元素 +### 通过标签名获取元素 -方法getElementsByTagName返回带有特定标签名称的所有子元素。实现该函数,这里注意是函数不是方法。该函数的参数是一个节点和字符串(标签名称),并返回一个数组,该数组包含所有带有特定标签名称的所有后代元素节点。 +document.getElementsByTagName方法返回带有特定标签名称的所有子元素。实现该函数,这里注意是函数不是方法。该函数的参数是一个节点和字符串(标签名称),并返回一个数组,该数组包含所有带有特定标签名称的所有后代元素节点。 -你可以使用tagName属性从DOM元素中获取标签名称。但这里需要注意,使用tagName获取的标签名称是全大写形式。可以使用字符串的toLowerCase或toUpperCase来解决这个问题。 +你可以使用nodeName属性从DOM元素中获取标签名称。但这里需要注意,使用tagName获取的标签名称是全大写形式。可以使用字符串的toLowerCase或toUpperCase来解决这个问题。 ```htmlHeading with a span element.@@ -536,27 +542,42 @@ Object.keys函数返回某个对象所有属性名称的数组,读者可能会 // → 1 console.log(byTagName(document.body, "span").length); // → 3 - var para = document.querySelector("p"); + let para = document.querySelector("p"); console.log(byTagName(para, "span").length); // → 2 ``` -#### 13.15.3 猫的帽子 +### 猫的帽子 扩展一下之前定义的用来绘制猫的动画函数,让猫和它的帽子沿着椭圆形轨道边(帽子永远在猫的对面)移动。 你也可以尝试让帽子环绕着猫移动,或修改成其他有趣的动画。 -为了便于定位多个对象,一个比较好的方法是使用绝对(absolute)定位。这就意味着top和left属性是相对于文档左上角的坐标。你可以简单地在坐标上加上一个固定数字,以避免出现负的坐标。 +为了便于定位多个对象,一个比较好的方法是使用绝对(absolute)定位。这就意味着top和left属性是相对于文档左上角的坐标。你可以简单地在坐标上加上一个固定数字,以避免出现负的坐标,它会使图像移出可见页面。 ```html +![]() ![]() |