寫(xiě)一個(gè)迷你 Dart 應(yīng)用
要點(diǎn)有哪些历筝?
- DartPad 讓你不需要 HTML 引用編寫(xiě)一個(gè)簡(jiǎn)單的 Dart web 應(yīng)用掖蛤。
- 一個(gè) Dart 應(yīng)用包括 Dart毡鉴、HTML石挂、和(通常)CSS 代碼博助。
- 編譯 一個(gè) web 應(yīng)用的 Dart 代碼為 JavaScript 來(lái)在任意現(xiàn)代瀏覽器中運(yùn)行此應(yīng)用。
- HTML 文件管理瀏覽器頁(yè)面中的 Dart 代碼痹愚。
- 樹(shù)/節(jié)點(diǎn)的 DOM 結(jié)構(gòu)富岳,模擬瀏覽器頁(yè)面。
- 使用帶 ID 的 querySelector() 來(lái)從 DOM 獲取元素拯腮。
- CSS 選擇器用來(lái)選擇匹配 DOM 中的元素窖式。
- 使用 CSS 規(guī)則來(lái)給元素添加樣式。
要寫(xiě)一個(gè) Dart web 應(yīng)用动壤,你需要明白幾個(gè)概念——DOM 樹(shù)萝喘、節(jié)點(diǎn)、元素琼懊、HTML阁簸,以及 Dart 語(yǔ)言和庫(kù)。
這些概念是相互依賴的哼丈,但我們必須從某個(gè)地方開(kāi)始启妹,所以我們從一個(gè)簡(jiǎn)單的 HTML 文件開(kāi)始,它介紹了 DOM 樹(shù)和節(jié)點(diǎn)削祈。從那里翅溺,你構(gòu)建一個(gè)視圖框架脑漫,從 Dart 應(yīng)用剝離動(dòng)態(tài)生成頁(yè)面的代碼。
雖然簡(jiǎn)單咙崎,但這個(gè)例子展示了如何連接 Dart 應(yīng)用和 HTML 頁(yè)面优幸,以及一個(gè) Dart 應(yīng)用如何與頁(yè)面上的元素相互作用。這些概念為更有趣褪猛、更有用的 web 應(yīng)用提供了基礎(chǔ)网杆。
關(guān)于 Dart, HTML, 以及 CSS
如果你用過(guò) DartPad,你已經(jīng)看到了讓你編寫(xiě) web 應(yīng)用代碼的 DART伊滋、HTML 和 CSS 標(biāo)簽碳却。這三個(gè)語(yǔ)言分別負(fù)責(zé) web 應(yīng)用的不同方面。
語(yǔ)言 | 用途 |
---|---|
Dart | 實(shí)現(xiàn) web 應(yīng)用的交互和動(dòng)態(tài)行為 |
HTML | 描述 web 應(yīng)用頁(yè)面的內(nèi)容(文檔和結(jié)構(gòu)中的元素) |
CSS | 控制頁(yè)面元素的外觀 |
Dart 程序可以響應(yīng)事件笑旺,例如鼠標(biāo)點(diǎn)擊昼浦,動(dòng)態(tài)地操作 web 頁(yè)面上的元素,以及保存信息筒主。在 web 應(yīng)用被部署之前关噪,Dart 代碼必須被編譯為 JavaScript 代碼。
HTML 是一種描述 web 頁(yè)面的語(yǔ)言乌妙。它使用標(biāo)簽設(shè)置頁(yè)面的初始結(jié)構(gòu)使兔,為頁(yè)面添加元素,并為頁(yè)面交互嵌入任意腳本藤韵。HTML 設(shè)置初始的文檔樹(shù)虐沥,并指定元素類(lèi)型、CSS 類(lèi)和 ID泽艘,這些允許 HTML欲险、CSS 和 Dart 程序來(lái)引用相同的元素。
CSS 表示層疊樣式表(Cascading Style Sheets)悉盆,描述了文檔中元素的外觀盯荤。CSS 控制格式的許多方面,例如:字體焕盟、字號(hào)秋秤、顏色、背景色脚翘、邊框灼卢、外邊距,以及對(duì)齊来农。
關(guān)于 DOM
文檔對(duì)象模型(DOM)表示作為節(jié)點(diǎn)樹(shù)的 web 文檔的結(jié)構(gòu)鞋真。當(dāng)一個(gè) HTML 文件被瀏覽器加載,瀏覽器解析 HTML 并在一個(gè)窗口顯示文檔沃于。下圖展示了一個(gè)簡(jiǎn)單的 HTML 文件以及在 Chrome 瀏覽器中生成的 web 頁(yè)面涩咖。
HTML 使用標(biāo)簽描述文檔海诲。例如,上圖簡(jiǎn)單的 HTML 代碼中使用<title>
標(biāo)簽描述頁(yè)面的標(biāo)題檩互,使用<h1>
描述一級(jí)標(biāo)題頭特幔,使用<p>
描述段落。在 HTML 代碼中的一些標(biāo)簽闸昨,比如<head>
和<body>
在 web 頁(yè)面是不可見(jiàn)的蚯斯,但對(duì)于文檔結(jié)構(gòu)是有用的。
在 DOM 中饵较,document 對(duì)象作為 DOM 樹(shù)的根(它沒(méi)有父節(jié)點(diǎn))拍嵌。在 DOM 樹(shù)中不同類(lèi)型的節(jié)點(diǎn)代表文檔中不同類(lèi)型的對(duì)象。例如循诉,DOM 樹(shù)包含頁(yè)面元素横辆、文本節(jié)點(diǎn)、屬性節(jié)點(diǎn)茄猫。下面是上圖中簡(jiǎn)單的 HTML 文件的 DOM 樹(shù)龄糊。
注意這些標(biāo)簽,比如<p>
段落標(biāo)簽募疮,它代表多個(gè)節(jié)點(diǎn)。段落本身是一個(gè)元素節(jié)點(diǎn)僻弹。段落中的文本是一個(gè)文本節(jié)點(diǎn)(有時(shí)候阿浓,可能是一個(gè)包含許多節(jié)點(diǎn)的子樹(shù))。ID 是一個(gè)屬性節(jié)點(diǎn)蹋绽。
除了根節(jié)點(diǎn)芭毙,每個(gè)節(jié)點(diǎn)在 DOM 樹(shù)中只有一個(gè)父節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)可以有多個(gè)子節(jié)點(diǎn)卸耘。
HTML 文件定義了文檔的初始結(jié)構(gòu)退敦。Dart 或 JavaScript 可以通過(guò)添加、刪除動(dòng)態(tài)地修改文檔蚣抗,并修改 DOM 樹(shù)中的節(jié)點(diǎn)侈百。當(dāng) DOM 發(fā)生改變,瀏覽器立刻重新渲染窗口翰铡。
上圖展示了一小段 Dart 程序钝域,它通過(guò)動(dòng)態(tài)更改一個(gè)段落文本來(lái)相應(yīng)地改變 DOM。程序可以添加和刪除節(jié)點(diǎn)锭魔,甚至插入整個(gè)子節(jié)點(diǎn)樹(shù)例证。
創(chuàng)建一個(gè)新的 Dart 應(yīng)用
- 進(jìn)入 DartPad。
- 點(diǎn)擊 New Pad 按鈕迷捧,撤銷(xiāo)你上次在 DartPad 做的所有更改织咧。
注意:這些 DartPad 的功能隱藏了一些 HTML 引用代碼胀葱。如果你想要使用任何其它的編輯器,我們推薦從一個(gè)小的 Dart web 應(yīng)用示例開(kāi)始笙蒙,并修改
<body>
中沒(méi)有<script>
標(biāo)簽的部分抵屿。HTML and Dart connections 展示了完整的 HTML 代碼。
編輯 HTML 源碼
- 點(diǎn)擊 DartPad 左上角的 HTML手趣。從 Dart 代碼視圖晌该,切換到(不存在的) HTML 代碼視圖。
- 添加下面的 HTML 代碼绿渣。
<p id="RipVanWinkle">
RipVanWinkle paragraph.
</p>
- 點(diǎn)擊 HTML OUTPUT 查看瀏覽器如何渲染 HTML朝群。
關(guān)于 HTML 源碼
這段 HTML 代碼和在本教程先前各種圖里顯示的 HTML 代碼相似,但它更簡(jiǎn)單中符。在 DartPad 中姜胖,你真正需要關(guān)心的唯一的標(biāo)簽——本例中的<p>
。你不需要關(guān)心包裹著它的標(biāo)簽淀散,例如<html>
和<body>
右莱。因?yàn)?DartPad 知道你的 Dart 代碼在哪里,你不需要一個(gè)<script>
標(biāo)簽档插。
注意:HTML and Dart connections 展示了在 DartPad 之外運(yùn)行 web 應(yīng)用的全部 HTML 代碼慢蜓。
這個(gè)段落標(biāo)簽有一個(gè)“RipVanWinkle”標(biāo)識(shí)符。你在下一步創(chuàng)建的 Dart 代碼會(huì)使用這個(gè) ID 來(lái)獲取段落元素郭膛。
編輯 Dart 源碼
- 點(diǎn)擊 DartPad 左上角的 DART晨抡。從 HTML 代碼視圖切換到 Dart 代碼視圖。
- 按如下所示修改 Dart 代碼则剃。
import 'dart:html';
void main() {
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
}
- 點(diǎn)擊 Run 來(lái)執(zhí)行代碼耘柱。
在 HTML OUTPUT 標(biāo)簽頁(yè)中的文本變?yōu)?“Wake up, sleepy head!”
關(guān)于 Dart 源碼
讓我們逐句查看這段 Dart 代碼。
導(dǎo)入庫(kù)
import
指令導(dǎo)入了指定的庫(kù)棍现,使這個(gè)庫(kù)里的所有類(lèi)和函數(shù)在你的程序里可用调煎。
import 'dart:html';
這段程序?qū)肓?Dart 的 HTML 庫(kù),它包含了操作 DOM 的關(guān)鍵類(lèi)和函數(shù)己肮。關(guān)鍵的類(lèi)有:
Dart 類(lèi) | 描述 |
---|---|
Node | 實(shí)現(xiàn)一個(gè) DOM 節(jié)點(diǎn)士袄。 |
Element | 一個(gè) Node 的子類(lèi);實(shí)現(xiàn)一個(gè) web 頁(yè)面元素谎僻。 |
Document | Node 的另一個(gè)子類(lèi)窖剑;實(shí)現(xiàn)文檔對(duì)象。 |
Dart 核心庫(kù)包含另外有用的類(lèi):List戈稿,一個(gè)可以指定它的成員類(lèi)型的參數(shù)化的類(lèi)西土。List<Element> 一個(gè) Element 保存它的子 Element 的列表的實(shí)例。
使用 querySelector() 函數(shù)
應(yīng)用的main()
函數(shù)包含一行代碼鞍盗,它有點(diǎn)像多個(gè)事情接連發(fā)生的連寫(xiě)語(yǔ)句需了。讓我們拆解它厌均。
querySelector()
是一個(gè)通過(guò) Dart HTML 庫(kù)提供的頂級(jí)函數(shù)块蚌,它從 DOM 獲取元素對(duì)象杰标。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
querySelector()
的參數(shù)——一個(gè)字符串丁存,是一個(gè)用于標(biāo)識(shí)該對(duì)象的 CSS 選擇器。最常見(jiàn)的 CSS 選擇器指定類(lèi)墓造、標(biāo)識(shí)符堪伍、或?qū)傩浴.?dāng)我們之后向迷你應(yīng)用中添加一個(gè) CSS 文件時(shí)觅闽,會(huì)詳細(xì)考慮這些選擇器帝雇。在本例中,RipVanWinkle
是 HTML 文件中聲明的段落元素的唯一 ID蛉拙,#RipVanWinkle
指定了這個(gè) ID尸闸。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
從 DOM 獲取元素的另一個(gè)有用的方法是querySelectorAll()
,它返回匹配提供的選擇器的所有元素對(duì)象的列表孕锄。
設(shè)置一個(gè)元素的文本
在 DOM 中吮廉,一個(gè)頁(yè)面元素的文本包含一個(gè)子節(jié)點(diǎn),具體而言畸肆,一個(gè)文本節(jié)點(diǎn)宦芦。在下圖中,包含字符串 “RipVanWinkle paragraph.” 的節(jié)點(diǎn)是一個(gè)文本節(jié)點(diǎn)轴脐。
更復(fù)雜的文本踪旷,例如,帶樣式變化或嵌入鏈接和圖片的文本豁辉,表現(xiàn)為一個(gè)文本節(jié)點(diǎn)和其它對(duì)象的子節(jié)點(diǎn)樹(shù)。
在 Dart 中舀患,你可以簡(jiǎn)單地使用元素地text
屬性徽级,它有一個(gè) getter 為你遍歷本節(jié)點(diǎn)的子節(jié)點(diǎn)樹(shù),并提取它們的文本聊浅。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
然而餐抢,如果這個(gè)文本節(jié)點(diǎn)有樣式(因此,是一個(gè)子節(jié)點(diǎn)樹(shù))低匙,獲取文本然后立刻設(shè)置它旷痕,可能會(huì)改變 DOM ,這是由于丟失了子節(jié)點(diǎn)樹(shù)的信息顽冶。通常欺抗,和我們的 RipVanWinkle 例子一樣,這種簡(jiǎn)化沒(méi)有副作用强重。
賦值操作符(=
)設(shè)置通過(guò)querySelector()
函數(shù)返回的元素的文本為字符串“Wake up, sleepy head!”绞呈。
querySelector('#RipVanWinkle').text = 'Wake up, sleepy head!';
這導(dǎo)致瀏覽器立刻重新渲染包含這個(gè)應(yīng)用的網(wǎng)頁(yè)贸人,從而在網(wǎng)頁(yè)上動(dòng)態(tài)地顯示文本。
HTML 和 Dart 相關(guān)聯(lián)
Dart web 應(yīng)用在運(yùn)行時(shí)動(dòng)態(tài)地改變?cè)跒g覽器窗口中的文本佃声。當(dāng)然艺智,只給網(wǎng)頁(yè)添加文本并不做其它事情可以直接由 HTML 完成。這個(gè)小應(yīng)用僅僅向你展示了如何連接一個(gè) Dart 應(yīng)用和一個(gè)網(wǎng)頁(yè)圾亏。
在 DartPad 中十拣,Dart 代碼和 HTML 代碼之間唯一的關(guān)聯(lián)是這個(gè)RipVanWinkle
ID。
要在 DartPad 之外運(yùn)行你的應(yīng)用志鹃,你需要編譯 Dart 代碼為 JavaScript夭问。使用 build_runner build 命令編譯你的應(yīng)用為可部署的 JavaScript。然后弄跌,你需要關(guān)聯(lián) HTML 和生成的 JavaScript:你必須在 HTML 添加<script>
標(biāo)簽來(lái)告訴瀏覽器在哪里找到編譯的 Dart 代碼甲喝。
下面是本應(yīng)用完整的 HTML 代碼,假設(shè) 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 給應(yīng)用添加樣式
大多數(shù) HTML 使用級(jí)聯(lián)樣式表(CSS)來(lái)定義樣式控制頁(yè)面元素的外觀铛只。讓我們?yōu)檫@個(gè)迷你應(yīng)用自定義 CSS埠胖。
- 點(diǎn)擊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 下面立刻顯示變化來(lái)反映新的樣式直撤,這僅應(yīng)用于 ID 是RipVanWinkle
的頁(yè)面元素。
關(guān)于 CSS 選擇器
CSS 選擇器可以是蜕着,關(guān)于在 HTML 中建立的元素的ID谋竖、CSS 類(lèi)和其它信息。你的 Dart 代碼可以使用這個(gè)信息通過(guò)一個(gè) CSS 選擇器來(lái)獲取元素——一個(gè)用來(lái)從 DOM 中選擇匹配元素的模式承匣。CSS 選擇器允許 CSS蓖乘、HTML 和 Dart 代碼來(lái)引用相同的對(duì)象。通常韧骗,一個(gè)選擇器指定一個(gè) ID嘉抒、一個(gè) HTML 元素類(lèi)型、一個(gè) CSS 類(lèi)或一個(gè)屬性袍暴。選擇器也可以被嵌套些侍。
CSS 選擇器在 Dart 程序中是很重要的,因?yàn)槟阃ㄟ^(guò)querySelector()
和querySelectorAll()
使用它們從 DOM 中獲取匹配的元素政模。很多時(shí)候岗宣,Dart 程序通過(guò)querySelector()
使用 ID 選擇器,通過(guò)querySelectorAll()
使用類(lèi)選擇器淋样。
下面是一些 CSS 選擇器的例子:
選擇器類(lèi)型 | 例子 | 描述 |
---|---|---|
ID 選擇器 | #RipVanWinkle | 匹配一個(gè)單一的耗式,唯一的元素 |
HTML 元素 | p | 匹配所有的段落 |
HTML 元素 | h1 | 匹配所有的 h1 標(biāo)題 |
CSS 類(lèi) | .classname | 匹配所有使用這個(gè)類(lèi)名的條目 |
通配符 | * | 匹配所有元素 |
屬性 | input[type=”button”] | 匹配所有 input 元素的按鈕 |
如你所見(jiàn),迷你應(yīng)用使用了一個(gè) CSS 選擇器——ID 選擇器
#RipVanWinkle
,即使當(dāng)時(shí)還沒(méi)有 CSS 文件纽什。你不需要為一個(gè) Dart 程序創(chuàng)建一個(gè) CSS 文件措嵌。你也不需要因要使用一個(gè) CSS 選擇器而創(chuàng)建一個(gè) CSS 文件。CSS 選擇器是建立在 HTML 文件中芦缰,并通過(guò) Dart 程序用來(lái)選擇匹配的元素企巢。
讓我們看看迷你應(yīng)用的 CSS 代碼。迷你應(yīng)用的 CSS 文件有一條 CSS 規(guī)則让蕾。一個(gè) CSS 規(guī)則有兩個(gè)主要部分:一個(gè)選擇器和一組聲明浪规。
在迷你應(yīng)用中,選擇器#RipVanWinkle
是一個(gè) ID 選擇器探孝,通過(guò)哈希符號(hào) (#
)標(biāo)識(shí)笋婿;它通過(guò)指定的 ID 匹配單獨(dú)的、唯一的元素——我們現(xiàn)在要替換的RipVanWinkle paragraph
元素顿颅。RipVanWinkle
是 HTML 文件中的 ID缸濒。在 CSS 文件和 Dart 代碼中使用哈希符號(hào)(#
)引用它。在 HTML 文件中指定類(lèi)名不需要句點(diǎn)(.
)粱腻,在 CSS 文件和 Dart 代碼中使用一個(gè)句點(diǎn)(.
)引用它庇配。
在 CSS 規(guī)則的花括號(hào)之中的是一系列聲明,每個(gè)都以分號(hào)(;
)結(jié)尾绍些。每個(gè)聲明指定一個(gè)屬性和它的值捞慌。這一組聲明合起來(lái)為所有匹配的元素定義了樣式表。樣式表用來(lái)設(shè)置在網(wǎng)頁(yè)上匹配元素的外觀柬批。
RipVanWinkle paragraph
元素的 CSS 規(guī)則指定了幾個(gè)屬性啸澡;例如,它設(shè)置文本顏色為黃色氮帐。
其它資源
- language tour 全面介紹了 Dart 語(yǔ)言嗅虏。
- Dart Tools 列出了包含 Dart 插件的 IDE 和編輯器。