mirror of
https://github.com/microsoft/Web-Dev-For-Beginners.git
synced 2025-08-19 04:52:06 +02:00
translate lesson 3 to zh-tw
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
|
||||
HTML (HyperText Markup Language) 可說是網頁的骨架。若說 CSS 打扮你的 HTML 而 JavaScript 讓它活起來,HTML 則是網頁應用的身體。HTML 的語法甚至佐證前行說明,它包含了 "head"、 "body" 和 "footer" 的標籤。
|
||||
|
||||
在這堂課中,我們會使用 HTML 去構建我們盆栽盒的虛擬介面。包含一個標題、三個欄位:左右各一的可拖曳植物盆栽欄位與中間的玻璃盆栽盒。這堂課程後,你會看到欄位中有許多盆栽,但介面可能會有點奇怪。不用擔心,往後的課程會講述 CSS 語法來造型化你的介面。
|
||||
在這堂課中,我們會使用 HTML 去構建我們盆栽盒的虛擬介面。包含一個標題、三個欄位:左右各一的可拖曳植物欄位與中間的玻璃盆栽罐。這堂課程後,你會看到欄位中有許多盆栽,但介面可能會有點奇怪。不用擔心,往後的課程會講述 CSS 語法來造型化你的介面。
|
||||
|
||||
### 課題
|
||||
|
||||
@@ -68,7 +68,7 @@ HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[
|
||||
|
||||
```html
|
||||
<head>
|
||||
<title>歡迎來到我的虛擬盆栽盒</title>
|
||||
<title>Welcome to my Virtual Terrarium</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
@@ -91,7 +91,7 @@ HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>歡迎來到我的虛擬盆栽盒</title>
|
||||
<title>Welcome to my Virtual Terrarium</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
@@ -180,7 +180,7 @@ HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[
|
||||
新增下列程式碼到你的 `<body>` 標籤中:
|
||||
|
||||
```html
|
||||
<h1>我的盆栽盒</h1>
|
||||
<h1>My Terrarium</h1>
|
||||
```
|
||||
|
||||
使用語義化標籤如:標題 `<h1>` 和未排序串列 `<ul>` ,能幫助螢幕報讀器理解網頁的內容。普遍來說,按鈕為 `<button>` 而串列為 `<li>`。我們當然 _可以_ 用自訂義包含按鈕事件的 `<span>` 元素來替代按鈕,但這對障礙者而言,無法直接地理解語法功用會是一種負擔。基於這項原因,盡量只使用語義化標籤。
|
||||
|
263
3-terrarium/2-intro-to-css/translations/README.zh-tw.md
Normal file
263
3-terrarium/2-intro-to-css/translations/README.zh-tw.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# 盆栽盒專案 Part 2: CSS 簡介
|
||||
|
||||

|
||||
> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製
|
||||
|
||||
## 課前測驗
|
||||
|
||||
[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17)
|
||||
|
||||
### 大綱
|
||||
|
||||
階層式樣式表,CSS (Cascading Style Sheets)解決了網頁開發重要的問題:如何讓網頁變得漂亮。為你的應用造型化可以讓網頁更好用、更好看。你也可以使用 CSS 建立回應式網頁設計(Responsive Web Design - RWD),依據你的視窗大小改變網頁的呈現方式。 CSS 不只讓網頁變美麗,它允許加入動畫以呈現更生動的互動體驗。CSS 工作組持續維護 CSS 的規格書,你可以在[全球資訊網協會官網](https://www.w3.org/Style/CSS/members)追蹤他們的作業。
|
||||
|
||||
> 筆記,CSS 是一種程式語言,但就像任何在網路上的東西一樣,並不是所有瀏覽器都支援最新的規格。請時常利用[CanIUse.com](https://caniuse.com)檢查你的設計是否支援相關瀏覽器。
|
||||
|
||||
這堂課中,我們會為我們的線上盆栽盒增加造型,學習更多 CSS 的概念:串接(Cascade)、繼承(Inheritance)、選擇器(Selectors)、定位(Positioning)與建立布局(Layout)。我們會規劃盆栽盒的布局,建立實際的盆栽盒。
|
||||
|
||||
### 開始之前
|
||||
|
||||
你需要確保你有盆栽盒的 HTML 程式碼,準備被造型化。
|
||||
|
||||
### 課題
|
||||
|
||||
在盆栽盒專案中,我們新增檔案 `style.css`。 在 HTML 檔案中匯入該檔案在 `<head>` 區塊中:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 串接(Cascade)
|
||||
|
||||
串接造型表單體現了造型依照表單上的優先度「串接」在網頁應用上。網頁作者利用程式碼設定造型優先度,行內樣式(inline styles)的優先度會比外部造型表單來的高。
|
||||
|
||||
### 課題
|
||||
|
||||
新增行內造型 "color: red" 到 `<h1>` 標籤中:
|
||||
|
||||
```HTML
|
||||
<h1 style="color: red">My Terrarium</h1>
|
||||
```
|
||||
|
||||
之後,也新增下列程式碼在 `style.css` 檔案中:
|
||||
|
||||
```CSS
|
||||
h1 {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
✅ 你的網頁顯示了哪一種顏色?為什麼?你能找到方法覆蓋這個造型嗎?何時會讓你想用這套做法呢?又為什麼不呢?
|
||||
|
||||
---
|
||||
|
||||
## 繼承(Inheritance)
|
||||
|
||||
從父關係標籤到子關係標籤上繼承造型,如被嵌套的物件會繼承容器物件的造型。
|
||||
|
||||
### 課題
|
||||
|
||||
我們設定 body 的字體為特定字型,確認嵌套物件的字型:
|
||||
|
||||
```CSS
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
開啟你的瀏覽器命令欄到 'Elements' 標籤中,觀察 H1 的字型。它繼承了 body 的字型,表現在瀏覽器上:
|
||||
|
||||

|
||||
|
||||
✅ 你能讓被嵌套元素繼承其他格式嗎?
|
||||
|
||||
---
|
||||
|
||||
## CSS 選擇器(Selectors)
|
||||
|
||||
### 標籤
|
||||
|
||||
到目前為止,你的 `style.css` 檔案只有一部份標籤被造型化,這讓程式看起來很怪:
|
||||
|
||||
```CSS
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #3a241d;
|
||||
text-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
這種造型方法只能控制被指定的元素,但如果你需要套用在每一種盆栽盒內的植物。你需要利用 CSS 選擇器。
|
||||
|
||||
### Ids
|
||||
|
||||
新增左容器與右容器造型布局。因為網頁內只有一個左容器與右容器,我們就這樣命名 id 標記。要造型化它們,使用 `#`:
|
||||
|
||||
```CSS
|
||||
#left-container {
|
||||
background-color: #eee;
|
||||
width: 15%;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#right-container {
|
||||
background-color: #eee;
|
||||
width: 15%;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
這裡,你已經將容器擺在絕對位置上了,一個位在左側,一個位在右側。容器寬度使用百分比以確保它們在小螢幕裝置上也能運作正常。
|
||||
|
||||
✅ 這兩段樣式已經重複了,請不要照抄。你能找到更好的方式來造型化這些 ids 嗎? 或許你可以從 id 或 class 來下手。讓 CSS 套用在容器上,我們需要改寫 HTML 程式碼:
|
||||
|
||||
```html
|
||||
<div id="left-container" class="container"></div>
|
||||
```
|
||||
|
||||
### Classes
|
||||
|
||||
在上述例子中,你成功地為兩樣物件新增造型。如果你想一次套用在多樣物件上,你就需要 CSS classes。利用這個方法來布局兩個容器。
|
||||
|
||||
注意每個植物的標記都有 ids 與 classes。JavaScript 使用 Id 標記來控制植物的擺放; class 則是被 CSS 套用特定的造型。
|
||||
|
||||
```html
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
|
||||
</div>
|
||||
```
|
||||
|
||||
新增下列程式碼到 `style.css` 檔案中:
|
||||
|
||||
```CSS
|
||||
.plant-holder {
|
||||
position: relative;
|
||||
height: 13%;
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
.plant {
|
||||
position: absolute;
|
||||
max-width: 150%;
|
||||
max-height: 150%;
|
||||
z-index: 2;
|
||||
}
|
||||
```
|
||||
|
||||
片段開頭是 CSS 的定位屬性,分為相對與絕對定位,我們會在下一個段落進行解述。我們來看看百分比高度的方式:
|
||||
|
||||
你設定了植物架高度為 13%,確保所有植物都能在不需要滾動容器的情況下,在每一個垂直的容器中顯示出來。
|
||||
|
||||
你設定了植物架向左移 10 像素,讓植物能在容器的正中間。圖片上亦有大區域的透明區域需要被拖曳過來,往左位移更適合呈現在畫面上。
|
||||
|
||||
之後,植物設定寬度為 150%。 當瀏覽器調整比例時,也能同時將植物圖片作大小的調整。試著改變瀏覽器檢視比例,植物依舊會保持在容器中。
|
||||
|
||||
我們換看 z-index,控制物件的相對高度,讓植物坐落在容器上方且在盆栽盒內部。
|
||||
|
||||
✅ 為什麼需要分為植物架與植物 CSS 選擇器?
|
||||
|
||||
## 定位(Positioning)
|
||||
|
||||
多樣的定位屬性,包含靜態(static)、相對(relative)、固定(fixed)、絕對(absolute)和黏貼(sticky),有時候讓人難以駕馭,但成功設定完後,可以讓你完整地掌握元素坐落的位置。
|
||||
|
||||
絕對定位元素會依照他的父關係物件來決定定位位置,若沒有關係物件,整個文件的 body 就會成為定位依據。
|
||||
|
||||
相對定位元素則依照 CSS 指定的方向來調整他的起始位置。
|
||||
|
||||
在我們的樣本中,`plant-holder` 是相對定位元素,坐落在絕對定位的容器當中。因此,容器被定義在左側與右側,而被嵌入的植物架會調整它在容器的位置,保持植物之間的間隔。
|
||||
|
||||
> `plant` 本身也擁有絕對定位,為了讓圖片被拖曳,你能在下段課程中發現更多資訊。
|
||||
|
||||
✅ 試著改變容器與植物架的定位模式。發生了什麼事?
|
||||
|
||||
## 布局(Layouts)
|
||||
|
||||
現在,你已經善用你所學的,只用 CSS 建出盆栽盒!
|
||||
|
||||
首先,對 `.terrarium` 的 div 子關係物件加上圓邊矩形:
|
||||
|
||||
```CSS
|
||||
.jar-walls {
|
||||
height: 80%;
|
||||
width: 60%;
|
||||
background: #d1e1df;
|
||||
border-radius: 10%;
|
||||
position: absolute;
|
||||
bottom: 0.5%;
|
||||
left: 20%;
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.jar-top {
|
||||
width: 50%;
|
||||
height: 5%;
|
||||
background: #d1e1df;
|
||||
position: absolute;
|
||||
bottom: 80.5%;
|
||||
left: 25%;
|
||||
opacity: 0.7;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.jar-bottom {
|
||||
width: 50%;
|
||||
height: 1%;
|
||||
background: #d1e1df;
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
left: 25%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.dirt {
|
||||
width: 58%;
|
||||
height: 5%;
|
||||
background: #3a241d;
|
||||
position: absolute;
|
||||
border-radius: 0 0 4rem 4rem;
|
||||
bottom: 1%;
|
||||
left: 21%;
|
||||
opacity: 0.7;
|
||||
z-index: -1;
|
||||
}
|
||||
```
|
||||
|
||||
注意這邊百分比的用法,即使是 `border-radius` 也請留意。 當瀏覽器調整檢視比例時,你會發現玻璃罐也會受到調整。 其他值得注意的地方為:玻璃罐的寬度與高度百分比,每個元素絕對定位在中心與視窗的下方。
|
||||
|
||||
✅ 試著改變罐子的顏色與透明度,觀察泥土與罐子的關係。發生了什麼事?為什麼?
|
||||
|
||||
---
|
||||
|
||||
## 🚀 挑戰
|
||||
|
||||
新增「氣泡反光」在罐子左下方的位置,讓玻璃材質更擬真一些。你需要編輯 `.jar-glossy-long` 與 `.jar-glossy-short` 造型集來模擬罐子反光。下面是成果圖:
|
||||
|
||||

|
||||
|
||||
在做課後測驗前,請先前往下列的學習頁面:[用 CSS 造型化你的網頁應用](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa)
|
||||
|
||||
## 課後測驗
|
||||
|
||||
[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/18)
|
||||
|
||||
## 複習與自學
|
||||
|
||||
CSS 看似很好上手,但要在所有瀏覽器與螢幕大小上運作正常,也會面臨到許多挑戰。CSS-Grid 與 Flexbox 這兩種工具讓上述作業變得比較好規劃與調整。藉由遊玩[Flexbox Froggy](https://flexboxfroggy.com/)與[Grid Garden](https://codepip.com/games/grid-garden/)來學習它們。
|
||||
|
||||
## 作業
|
||||
|
||||
[重構 CSS](assignment.zh-tw.md)
|
11
3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md
Normal file
11
3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# 重構 CSS
|
||||
|
||||
## 簡介
|
||||
|
||||
使用 Flexbox 或 CSS Grid 重新規劃盆栽盒,拍幾張在不同瀏覽器上運作的畫面。重新規劃時,你可能需要改變程式碼中版本的標記。不需要去考慮植物拖曳的問題,我們只重構 HTML 與 CSS 的部分。
|
||||
|
||||
## 學習評量
|
||||
|
||||
| 作業內容 | 優良 | 普通 | 待改進 |
|
||||
| -------- | --------------------------------------- | ---------------- | -------------------- |
|
||||
| | 使用 Flexbox 或 CSS Grid 呈現新的盆栽盒 | 重新取代部分元素 | 無法更新原有的盆栽盒 |
|
@@ -0,0 +1,219 @@
|
||||
# 盆栽盒專案 Part 3 - DOM 元素控制與閉包
|
||||
|
||||

|
||||
> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製
|
||||
|
||||
## 課前測驗
|
||||
|
||||
[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19)
|
||||
|
||||
### 大綱
|
||||
|
||||
操作 DOM (Document Object Model) 是網頁開發的一項關鍵。根據[MDN 文件](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), 「Document Object Model (DOM) 元素能根據網頁文件的結構與內容來呈現物件」。藉由使用 JavaScript 框架而非原始的 JavaScript 程式碼來管理 DOM,在網頁上操作 DOM 的挑戰已經不比以前困難了,但這裡我們要自己來管理它們!
|
||||
|
||||
此外,這堂課也會介紹有關[JavaScript 閉包(Closure)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)的概念,你可以想像成一個函式被包在另一個函式中,以訪問外面函式範圍中的變數。
|
||||
|
||||
> JavaScript 閉包是個廣闊且複雜的主題。本堂課只觸及建立盆栽盒需要的最基礎概念。你能得知一個閉包為:內部函式和外部函式建立一項關係,允許內部函式存取外部函式的變數等作用域。要得知更多關於閉包的原理,請造訪觀看[額外的文件](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)。
|
||||
|
||||
我們會使用閉包來操控 DOM。
|
||||
|
||||
想像 DOM 就像一棵樹,表現出所有操作網頁的方式。多樣的 APIs (Application Program Interfaces) 提供程式開發者,依照自己使用的程式語言,以存取、編輯、編排等方式管理 DOM 元素。
|
||||
|
||||

|
||||
|
||||
> HTML 語法會參考 DOM 的呈現方式。出自 [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)。
|
||||
|
||||
在這堂課中,我們會完成我們的盆栽盒專案,建立 JavaScript 來對網頁中的植物進行互動式操作。
|
||||
|
||||
### 開始之前
|
||||
|
||||
確保盆栽盒的 HTML 與 CSS 已經編輯完成。這堂課會新增拖曳植物進出盆栽罐的功能。
|
||||
|
||||
### 課題
|
||||
|
||||
在專案資料夾中,新增檔案 `script.js`。 匯入該檔案在 HTML 檔 `<head>` 的部分:
|
||||
|
||||
```html
|
||||
<script src="./script.js" defer></script>
|
||||
```
|
||||
|
||||
> 筆記:匯入外部 JavaScript 檔案到 HTML 檔案須使用 `defer`,讓 JavaScript 檔案只有在 HTML 被完全載入時才被執行。你也可以使用 `async` 的屬性,允許 JavaScript 在解析 HTML 檔時就被執行。這項專案中,我們必須確保 HTML 的元件被完整建立後才允許使用拖曳功能。
|
||||
---
|
||||
|
||||
## DOM 元素
|
||||
|
||||
我們要做的第一件事是建立 DOM 下,要被操控的物件的連結。在專案例子中,我們有罐子外的十四株植物等著被拖曳。
|
||||
|
||||
### 課題
|
||||
|
||||
```html
|
||||
dragElement(document.getElementById('plant1'));
|
||||
dragElement(document.getElementById('plant2'));
|
||||
dragElement(document.getElementById('plant3'));
|
||||
dragElement(document.getElementById('plant4'));
|
||||
dragElement(document.getElementById('plant5'));
|
||||
dragElement(document.getElementById('plant6'));
|
||||
dragElement(document.getElementById('plant7'));
|
||||
dragElement(document.getElementById('plant8'));
|
||||
dragElement(document.getElementById('plant9'));
|
||||
dragElement(document.getElementById('plant10'));
|
||||
dragElement(document.getElementById('plant11'));
|
||||
dragElement(document.getElementById('plant12'));
|
||||
dragElement(document.getElementById('plant13'));
|
||||
dragElement(document.getElementById('plant14'));
|
||||
```
|
||||
|
||||
發生了什麼事?你正以 DOM 搜尋網頁檔內的物件,藉由 Id 作為依據來搜尋。回想第一堂 HTML 課中,我們可每一株植物一個專屬的 Id (`id="plant1"`),現在你就可以使用它。在辨別完每一株植物物件後,傳遞給待編輯的函式 `dragElement`,讓 HTML 物件可以被拖曳。
|
||||
|
||||
✅ 為什麼我們要以 Id 作為物件的參考?為什麼不以 CSS 的 class 作為參考?請參考以前的 CSS 課程回答此問題。
|
||||
|
||||
---
|
||||
|
||||
## 閉包(Closure)
|
||||
|
||||
現在,你已經準備好要建立 dragElement 閉包,建立包在外部函式內的內部函式組,在我們的例子中,會用上三個函式。
|
||||
|
||||
閉包在一或多個以上函式要存取外部函式時非常好用。看看下面的例子:
|
||||
|
||||
```javascript
|
||||
function displayCandy(){
|
||||
let candy = ['jellybeans'];
|
||||
function addCandy(candyType) {
|
||||
candy.push(candyType)
|
||||
}
|
||||
addCandy('gumdrops');
|
||||
}
|
||||
displayCandy();
|
||||
console.log(candy)
|
||||
```
|
||||
|
||||
這項例子中,函式 displayCandy 包住另一個函式 addCandy,新增新的糖果樣式到已存在的矩陣當中。當執行這段程式時,矩陣 `candy` 會被認作是未定義,因為它是函式的本地變數。
|
||||
|
||||
✅ 你能讓矩陣 `candy` 被存取嗎?試著將它移到閉包外面。這時,矩陣會變成全域變數,取消閉包內的存取限制。
|
||||
|
||||
### 課題
|
||||
|
||||
在檔案 `script.js` 的元素宣告下方,新增函式:
|
||||
|
||||
```javascript
|
||||
function dragElement(terrariumElement) {
|
||||
//set 4 positions for positioning on the screen
|
||||
let pos1 = 0,
|
||||
pos2 = 0,
|
||||
pos3 = 0,
|
||||
pos4 = 0;
|
||||
terrariumElement.onpointerdown = pointerDrag;
|
||||
}
|
||||
```
|
||||
|
||||
`dragElement` 藉由程式定義的參數取得 `terrariumElement` 物件。之後,設定一些位置 `0` 的變數給函式內的物件使用。它們是本地變數,給每一個進到拖曳函式內的物件操控。盆栽盒會被這些拖曳物件填充,我們的網頁應用必須要持續追蹤這些物件的位置。
|
||||
|
||||
此外,進到函式的 terrariumElement 也被新增了 `pointerdown` 事件,它是管理 DOM 的其中一項[網頁 APIs](https://developer.mozilla.org/en-US/docs/Web/API)。當按鈕按下時,或是在我們案例中,一個拖曳物件被點擊時,`onpointerdown` 事件就會被觸發。這個事件處理器(event handler)皆運作在[網頁與行動瀏覽器](https://caniuse.com/?search=onpointerdown)上,只有少部分的例外。
|
||||
|
||||
✅ [事件處理器 `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick)支援更多的瀏覽器。為什麼我們不在這邊使用它? 想想看我們在這此建立的視窗互動類型。
|
||||
|
||||
---
|
||||
|
||||
## 函式 pointerDrag
|
||||
|
||||
terrariumElement 已經準備好被拖曳了。當觸發 `onpointerdown` 事件時,函式 pointerDrag 會參與其中。新增這項函式在程式碼 `terrariumElement.onpointerdown = pointerDrag;` 下方:
|
||||
|
||||
### 課題
|
||||
|
||||
```javascript
|
||||
function pointerDrag(e) {
|
||||
e.preventDefault();
|
||||
console.log(e);
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
}
|
||||
```
|
||||
|
||||
許多事情會發生。首先,你使用 `e.preventDefault();` 取消掉 pointerdown 原先的預設事件。這樣你可以操作更多的介面行為。
|
||||
|
||||
> 回到你建立的程式碼中,試著刪除 `e.preventDefault()` 並執行看看,發生了什麼事?
|
||||
|
||||
第二,用瀏覽器打開 `index.html` 並調查我們的介面。當你點擊植物時,你可以發現 'e' 事件被觸發了。專研一下,一個 pointerdown 事件會產生多少資訊!
|
||||
|
||||
接下來,紀錄本地變數 `pos3` 和 `pos4` 被設定為 e.clientX 和 e.clientY。你可以在觀察面板中,會發現 `e` 的數值。這項數值取得按下植物瞬間的 x 與 y 座標資訊。為了全面的控制植物行為,在拖曳植物時,我們會持續更新座標資訊。
|
||||
|
||||
✅ 將整個網頁應用建立在一個大閉包下,會讓程式碼變得比較清楚嗎?如果沒有,你有其他方法管理這十四株可拖曳的植物嗎?
|
||||
|
||||
增加初始化函式,在程式碼 `pos4 = e.clientY` 下方加上下列兩行事件處理:
|
||||
|
||||
```html
|
||||
document.onpointermove = elementDrag;
|
||||
document.onpointerup = stopElementDrag;
|
||||
```
|
||||
|
||||
現在,在游標拖曳時,你的植物能跟著你的游標走,而在你取消點擊時停下來。`onpointermove` 和 `onpointerup` 也是 `onpointerdown` 類型相同的 API。然而,現在介面會出現錯誤訊息,因為我們還沒建立函式 `elementDrag` 與 `stopElementDrag`。
|
||||
|
||||
## 函式 elementDrag 與 stopElementDrag
|
||||
|
||||
新增兩條內部函式在閉包中,它們會處理拖曳植物與停止拖曳的事件。你希望你可以拖曳任何一株植物且放在螢幕上的任一地方。介面並沒有強制你盆栽盒的配置格式,你可以自由地增加、移除與移動盆栽罐內的植物。
|
||||
|
||||
### 課題
|
||||
|
||||
新增函式 `elementDrag` 在函式閉包 `pointerDrag` 宣告列的正下方:
|
||||
|
||||
```javascript
|
||||
function elementDrag(e) {
|
||||
pos1 = pos3 - e.clientX;
|
||||
pos2 = pos4 - e.clientY;
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
console.log(pos1, pos2, pos3, pos4);
|
||||
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
|
||||
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
|
||||
}
|
||||
```
|
||||
|
||||
在這條函式之前,你編輯了四個本地變數位置的初始值在外部函式中。這邊又做了什麼事?
|
||||
|
||||
當你拖曳物件時,你更新數值 `pos1` 為 `pos3` 減去現在的 `e.clientX`,而 `pos3` 在之前被初始化為為 `e.clientX`。同樣的行為套用在 `pos2`上。之後,你更新 `pos3` 與 `pos4` 到新的 XY 座標點位置。你能在 console 下看到數值在拖曳下更新的情況。我們也更新植物的 CSS 造型中的定位點為 `pos1` 與 `pos2`,比較植物左上方座標點與新座標點的關係。
|
||||
|
||||
> `offsetTop` 和 `offsetLeft` 是 CSS 的屬性,決定物件與它父關係物件的定位關係。父關係物件可以是任何元素,只要它的定位屬性不為 `static`。
|
||||
|
||||
這些座標點的計算式讓你成功校整了植物與盆栽盒之間的行為。
|
||||
|
||||
### 課題
|
||||
|
||||
最後的課題是在介面上新增 `stopElementDrag` 函式,我們將它加在函式閉包 `elementDrag` 的正下方:
|
||||
|
||||
```javascript
|
||||
function stopElementDrag() {
|
||||
document.onpointerup = null;
|
||||
document.onpointermove = null;
|
||||
}
|
||||
```
|
||||
|
||||
這條小函式重制 `onpointerup` 與 `onpointermove` 事件,這樣你可以重新開始該植物的拖曳事件,或是拖曳新的植物。
|
||||
|
||||
✅ 如果不將這些事件設為空值時,會發生什麼事?
|
||||
|
||||
我們終於完成了這項專案!
|
||||
|
||||
🥇 恭喜你!你建立了一個漂亮的盆栽盒。
|
||||
|
||||
---
|
||||
|
||||
## 🚀 挑戰
|
||||
|
||||
新增新的事件處理器到你的閉包中,讓你能對植物做更多的事情。舉例來說,雙擊植物讓它排列到最上層。發揮你的創意吧!
|
||||
|
||||
## 課後測驗
|
||||
|
||||
[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/20)
|
||||
|
||||
## 複習與自學
|
||||
|
||||
在螢幕上拖曳物件看似簡單,但依照不同的目的與實現方法會遭遇到不同的問題。事實上,這邊有一份關於你可以嘗試的[拖曳 API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)。我們沒在專案中使用是為了建立不一樣的實現方法,試著使用這些 API 到專案中,看看你能完成什麼。
|
||||
|
||||
在[W3C 文件](https://www.w3.org/TR/pointerevents1/) 和 [MDN 網頁文件](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events)上取得更多關於 pointer 的事件。
|
||||
|
||||
記得習慣性用[CanIUse.com](https://caniuse.com/)檢查網頁的瀏覽器兼容性。
|
||||
|
||||
## 作業
|
||||
|
||||
[用 DOM 做更多事](assignment.zh-tw.md)
|
||||
|
@@ -0,0 +1,11 @@
|
||||
# 用 DOM 做更多事
|
||||
|
||||
## 簡介
|
||||
|
||||
調查其中一項 DOM 的元素。造訪 MSN 關於[DOM 介面的清單](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)挑選其中一項。在網路上找尋一個使用這項元素的網頁,並解釋如何使用它。
|
||||
|
||||
## 學習評量
|
||||
|
||||
| 作業內容 | 優良 | 普通 | 待改進 |
|
||||
| -------- | ---------------------- | ---------------- | ---------------- |
|
||||
| | 完整的評論文章附帶例子 | 評論文章不帶例子 | 評論文章並不完整 |
|
34
3-terrarium/translations/README.zh-tw.md
Normal file
34
3-terrarium/translations/README.zh-tw.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 我的盆栽盒:一個關於 HTML、CSS 與 JavaScript DOM 控制的專案 🌵🌱
|
||||
|
||||
深思一項小型互動式拖放程式專案,在 HTML、JS 與 CSS 的帶領下,你可以建立網頁介面,美化它,並增加互動功能。
|
||||
|
||||

|
||||
|
||||
# 課程
|
||||
|
||||
1. [HTML 簡介](../1-intro-to-html/translations/README.zh-tw.md)
|
||||
2. [CSS 簡介](../2-intro-to-css/translations/README.zh-tw.md)
|
||||
3. [DOM 簡介與閉包](../translations/3-intro-to-DOM-and-closures/README.zh-tw.md)
|
||||
|
||||
## 參與人員
|
||||
|
||||
由 [Jen Looper](https://www.twitter.com/jenlooper) 用滿滿的 ♥️ 來編寫。
|
||||
|
||||
用 CSS 建立盆栽盒的發想來自於 Jakub Mandra 的玻璃罐 [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY)。
|
||||
|
||||
手繪插圖由 [Jen Looper](http://jenlooper.com) 使用 Procreate 繪製。
|
||||
|
||||
## 建置你的盆栽盒
|
||||
|
||||
你可以利用 Azure Static Web Apps 建置、發布你的盆栽盒到網路上。
|
||||
|
||||
1. 分叉這個數據庫
|
||||
|
||||
2. 按下下方按鈕
|
||||
|
||||
[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-13441-cxa#create/Microsoft.StaticApp)
|
||||
|
||||
3. 遵循指示建立你的網頁應用。請確保你的程式根目錄為 `/solution` 或者是你自己的專案位置。這項專案並不包含任何 API,你不需要考慮額外匯入的問題。 .github 資料夾會建立在你的分叉數據庫中,它會幫助 Azure Static Web Apps 的組建服務並發布你的應用到新的網址。
|
||||
|
||||
|
||||
|
@@ -858,7 +858,7 @@
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"title": "課程九 - 盆栽盒專案 - CSS簡介:課前測驗",
|
||||
"title": "課程九 - 盆栽盒專案 - CSS 簡介:課前測驗",
|
||||
"quiz": [
|
||||
{
|
||||
"questionText": "HTML 元素必須包含 class 或 id 才能被造型化。",
|
||||
@@ -903,7 +903,7 @@
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"title": "課程九 - 盆栽盒專案 - CSS簡介:課後測驗",
|
||||
"title": "課程九 - 盆栽盒專案 - CSS 簡介:課後測驗",
|
||||
"quiz": [
|
||||
{
|
||||
"questionText": "CSS 可以被撰寫在 HTML 檔案的開頭。",
|
||||
@@ -959,7 +959,7 @@
|
||||
"title": "課程十 - 盆栽盒專案 - DOM 元素控制與閉包:課前測驗",
|
||||
"quiz": [
|
||||
{
|
||||
"questionText": "DOM 元素全名為 Document Object Management",
|
||||
"questionText": "DOM 全名為 Document Object Management",
|
||||
"answerOptions": [
|
||||
{
|
||||
"answerText": "是",
|
||||
@@ -972,7 +972,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"questionText": "可以將 DOM 元素理解為樹的一種。",
|
||||
"questionText": "可以將 DOM 理解為樹的一種。",
|
||||
"answerOptions": [
|
||||
{
|
||||
"answerText": "是",
|
||||
@@ -985,7 +985,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"questionText": "利用 Web API,開發人員就能控制 DOM 元素。",
|
||||
"questionText": "利用網頁 API,開發人員就能控制 DOM 元素。",
|
||||
"answerOptions": [
|
||||
{
|
||||
"answerText": "是",
|
||||
|
Reference in New Issue
Block a user