写一个迷你 Dart 应用
要点有哪些?
- DartPad 让你不需要 HTML 引用编写一个简单的 Dart web 应用。
- 一个 Dart 应用包括 Dart、HTML、和(通常)CSS 代码。
- 编译 一个 web 应用的 Dart 代码为 JavaScript 来在任意现代浏览器中运行此应用。
- HTML 文件管理浏览器页面中的 Dart 代码。
- 树/节点的 DOM 结构,模拟浏览器页面。
- 使用带 ID 的 querySelector() 来从 DOM 获取元素。
- CSS 选择器用来选择匹配 DOM 中的元素。
- 使用 CSS 规则来给元素添加样式。
要写一个 Dart web 应用,你需要明白几个概念——DOM 树、节点、元素、HTML,以及 Dart 语言和库。
这些概念是相互依赖的,但我们必须从某个地方开始,所以我们从一个简单的 HTML 文件开始,它介绍了 DOM 树和节点。从那里,你构建一个视图框架,从 Dart 应用剥离动态生成页面的代码。
虽然简单,但这个例子展示了如何连接 Dart 应用和 HTML 页面,以及一个 Dart 应用如何与页面上的元素相互作用。这些概念为更有趣、更有用的 web 应用提供了基础。
关于 Dart, HTML, 以及 CSS
如果你用过 DartPad,你已经看到了让你编写 web 应用代码的 DART、HTML 和 CSS 标签。这三个语言分别负责 web 应用的不同方面。
语言 | 用途 |
---|---|
Dart | 实现 web 应用的交互和动态行为 |
HTML | 描述 web 应用页面的内容(文档和结构中的元素) |
CSS | 控制页面元素的外观 |
Dart 程序可以响应事件,例如鼠标点击,动态地操作 web 页面上的元素,以及保存信息。在 web 应用被部署之前,Dart 代码必须被编译为 JavaScript 代码。
HTML 是一种描述 web 页面的语言。它使用标签设置页面的初始结构,为页面添加元素,并为页面交互嵌入任意脚本。HTML 设置初始的文档树,并指定元素类型、CSS 类和 ID,这些允许 HTML、CSS 和 Dart 程序来引用相同的元素。
CSS 表示层叠样式表(Cascading Style Sheets),描述了文档中元素的外观。CSS 控制格式的许多方面,例如:字体、字号、颜色、背景色、边框、外边距,以及对齐。
关于 DOM
文档对象模型(DOM)表示作为节点树的 web 文档的结构。当一个 HTML 文件被浏览器加载,浏览器解析 HTML 并在一个窗口显示文档。下图展示了一个简单的 HTML 文件以及在 Chrome 浏览器中生成的 web 页面。
HTML 使用标签描述文档。例如,上图简单的 HTML 代码中使用<title>
标签描述页面的标题,使用<h1>
描述一级标题头,使用<p>
描述段落。在 HTML 代码中的一些标签,比如<head>
和<body>
在 web 页面是不可见的,但对于文档结构是有用的。
在 DOM 中,document 对象作为 DOM 树的根(它没有父节点)。在 DOM 树中不同类型的节点代表文档中不同类型的对象。例如,DOM 树包含页面元素、文本节点、属性节点。下面是上图中简单的 HTML 文件的 DOM 树。
注意这些标签,比如<p>
段落标签,它代表多个节点。段落本身是一个元素节点。段落中的文本是一个文本节点(有时候,可能是一个包含许多节点的子树)。ID 是一个属性节点。
除了根节点,每个节点在 DOM 树中只有一个父节点。每个节点可以有多个子节点。
HTML 文件定义了文档的初始结构。Dart 或 JavaScript 可以通过添加、删除动态地修改文档,并修改 DOM 树中的节点。当 DOM 发生改变,浏览器立刻重新渲染窗口。
上图展示了一小段 Dart 程序,它通过动态更改一个段落文本来相应地改变 DOM。程序可以添加和删除节点,甚至插入整个子节点树。
创建一个新的 Dart 应用
- 进入 DartPad。
- 点击 New Pad 按钮,撤销你上次在 DartPad 做的所有更改。
注意:这些 DartPad 的功能隐藏了一些 HTML 引用代码。如果你想要使用任何其它的编辑器,我们推荐从一个小的 Dart web 应用示例开始,并修改
<body>
中没有<script>
标签的部分。HTML and Dart connections 展示了完整的 HTML 代码。
编辑 HTML 源码
- 点击 DartPad 左上角的 HTML。从 Dart 代码视图,切换到(不存在的) HTML 代码视图。
- 添加下面的 HTML 代码。
<p id="RipVanWinkle">
RipVanWinkle paragraph.
</p>
- 点击 HTML OUTPUT 查看浏览器如何渲染 HTML。
关于 HTML 源码
这段 HTML 代码和在本教程先前各种图里显示的 HTML 代码相似,但它更简单。在 DartPad 中,你真正需要关心的唯一的标签——本例中的<p>
。你不需要关心包裹着它的标签,例如<html>
和<body>
。因为 DartPad 知道你的 Dart 代码在哪里,你不需要一个<script>
标签。
注意:HTML and Dart connections 展示了在 DartPad 之外运行 web 应用的全部 HTML 代码。
这个段落标签有一个“RipVanWinkle”标识符。你在下一步创建的 Dart 代码会使用这个 ID 来获取段落元素。
编辑 Dart 源码
- 点击 DartPad 左上角的 DART。从 HTML 代码视图切换到 Dart 代码视图。
- 按如下所示修改 Dart 代码。
import 'dart:html';
void main() {
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
}
- 点击 Run 来执行代码。
在 HTML OUTPUT 标签页中的文本变为 “Wake up, sleepy head!”
关于 Dart 源码
让我们逐句查看这段 Dart 代码。
导入库
import
指令导入了指定的库,使这个库里的所有类和函数在你的程序里可用。
import 'dart:html';
这段程序导入了 Dart 的 HTML 库,它包含了操作 DOM 的关键类和函数。关键的类有:
Dart 类 | 描述 |
---|---|
Node | 实现一个 DOM 节点。 |
Element | 一个 Node 的子类;实现一个 web 页面元素。 |
Document | Node 的另一个子类;实现文档对象。 |
Dart 核心库包含另外有用的类:List,一个可以指定它的成员类型的参数化的类。List<Element> 一个 Element 保存它的子 Element 的列表的实例。
使用 querySelector() 函数
应用的main()
函数包含一行代码,它有点像多个事情接连发生的连写语句。让我们拆解它。
querySelector()
是一个通过 Dart HTML 库提供的顶级函数,它从 DOM 获取元素对象。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
querySelector()
的参数——一个字符串,是一个用于标识该对象的 CSS 选择器。最常见的 CSS 选择器指定类、标识符、或属性。当我们之后向迷你应用中添加一个 CSS 文件时,会详细考虑这些选择器。在本例中,RipVanWinkle
是 HTML 文件中声明的段落元素的唯一 ID,#RipVanWinkle
指定了这个 ID。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
从 DOM 获取元素的另一个有用的方法是querySelectorAll()
,它返回匹配提供的选择器的所有元素对象的列表。
设置一个元素的文本
在 DOM 中,一个页面元素的文本包含一个子节点,具体而言,一个文本节点。在下图中,包含字符串 “RipVanWinkle paragraph.” 的节点是一个文本节点。
更复杂的文本,例如,带样式变化或嵌入链接和图片的文本,表现为一个文本节点和其它对象的子节点树。
在 Dart 中,你可以简单地使用元素地text
属性,它有一个 getter 为你遍历本节点的子节点树,并提取它们的文本。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
然而,如果这个文本节点有样式(因此,是一个子节点树),获取文本然后立刻设置它,可能会改变 DOM ,这是由于丢失了子节点树的信息。通常,和我们的 RipVanWinkle 例子一样,这种简化没有副作用。
赋值操作符(=
)设置通过querySelector()
函数返回的元素的文本为字符串“Wake up, sleepy head!”。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
这导致浏览器立刻重新渲染包含这个应用的网页,从而在网页上动态地显示文本。
HTML 和 Dart 相关联
Dart web 应用在运行时动态地改变在浏览器窗口中的文本。当然,只给网页添加文本并不做其它事情可以直接由 HTML 完成。这个小应用仅仅向你展示了如何连接一个 Dart 应用和一个网页。
在 DartPad 中,Dart 代码和 HTML 代码之间唯一的关联是这个RipVanWinkle
ID。
要在 DartPad 之外运行你的应用,你需要编译 Dart 代码为 JavaScript。使用 build_runner build 命令编译你的应用为可部署的 JavaScript。然后,你需要关联 HTML 和生成的 JavaScript:你必须在 HTML 添加<script>
标签来告诉浏览器在哪里找到编译的 Dart 代码。
下面是本应用完整的 HTML 代码,假设 Dart 代码是在名为main.dart
的文件中:
<!DOCTYPE html>
<html>
<head>
<title>A Minimalist App</title>
<script defer src="main.dart.js"></script>
</head>
<body>
<p id="RipVanWinkle">
RipVanWinkle paragraph.
</p>
</body>
</html>
使用 CSS 给应用添加样式
大多数 HTML 使用级联样式表(CSS)来定义样式控制页面元素的外观。让我们为这个迷你应用自定义 CSS。
- 点击CSS。从 Dart 代码视图切换到(不存在的) CSS 代码视图。
- 添加下面的 CSS 代码:
#RipVanWinkle {
font-size: 20px;
font-family: 'Open Sans', sans-serif;
text-align: center;
margin-top: 20px;
background-color: SlateBlue;
color: Yellow;
}
在 HTML OUTPUT 下面立刻显示变化来反映新的样式,这仅应用于 ID 是RipVanWinkle
的页面元素。
关于 CSS 选择器
CSS 选择器可以是,关于在 HTML 中建立的元素的ID、CSS 类和其它信息。你的 Dart 代码可以使用这个信息通过一个 CSS 选择器来获取元素——一个用来从 DOM 中选择匹配元素的模式。CSS 选择器允许 CSS、HTML 和 Dart 代码来引用相同的对象。通常,一个选择器指定一个 ID、一个 HTML 元素类型、一个 CSS 类或一个属性。选择器也可以被嵌套。
CSS 选择器在 Dart 程序中是很重要的,因为你通过querySelector()
和querySelectorAll()
使用它们从 DOM 中获取匹配的元素。很多时候,Dart 程序通过querySelector()
使用 ID 选择器,通过querySelectorAll()
使用类选择器。
下面是一些 CSS 选择器的例子:
选择器类型 | 例子 | 描述 |
---|---|---|
ID 选择器 | #RipVanWinkle | 匹配一个单一的,唯一的元素 |
HTML 元素 | p | 匹配所有的段落 |
HTML 元素 | h1 | 匹配所有的 h1 标题 |
CSS 类 | .classname | 匹配所有使用这个类名的条目 |
通配符 | * | 匹配所有元素 |
属性 | input[type=”button”] | 匹配所有 input 元素的按钮 |
如你所见,迷你应用使用了一个 CSS 选择器——ID 选择器
#RipVanWinkle
,即使当时还没有 CSS 文件。你不需要为一个 Dart 程序创建一个 CSS 文件。你也不需要因要使用一个 CSS 选择器而创建一个 CSS 文件。CSS 选择器是建立在 HTML 文件中,并通过 Dart 程序用来选择匹配的元素。
让我们看看迷你应用的 CSS 代码。迷你应用的 CSS 文件有一条 CSS 规则。一个 CSS 规则有两个主要部分:一个选择器和一组声明。
在迷你应用中,选择器#RipVanWinkle
是一个 ID 选择器,通过哈希符号 (#
)标识;它通过指定的 ID 匹配单独的、唯一的元素——我们现在要替换的RipVanWinkle paragraph
元素。RipVanWinkle
是 HTML 文件中的 ID。在 CSS 文件和 Dart 代码中使用哈希符号(#
)引用它。在 HTML 文件中指定类名不需要句点(.
),在 CSS 文件和 Dart 代码中使用一个句点(.
)引用它。
在 CSS 规则的花括号之中的是一系列声明,每个都以分号(;
)结尾。每个声明指定一个属性和它的值。这一组声明合起来为所有匹配的元素定义了样式表。样式表用来设置在网页上匹配元素的外观。
RipVanWinkle paragraph
元素的 CSS 规则指定了几个属性;例如,它设置文本颜色为黄色。
其它资源
- language tour 全面介绍了 Dart 语言。
- Dart Tools 列出了包含 Dart 插件的 IDE 和编辑器。