From 330e21601528f1a7ace181eba5f87279fcc193ce Mon Sep 17 00:00:00 2001 From: CRTao Date: Thu, 18 Feb 2021 10:02:42 +0800 Subject: [PATCH 01/13] translate quiz to zh-tw --- quiz-app/src/App.vue | 1 + quiz-app/src/assets/translations/index.js | 2 + quiz-app/src/assets/translations/zh-tw.json | 2509 +++++++++++++++++++ 3 files changed, 2512 insertions(+) create mode 100644 quiz-app/src/assets/translations/zh-tw.json diff --git a/quiz-app/src/App.vue b/quiz-app/src/App.vue index 41b741aa..7890cf0e 100644 --- a/quiz-app/src/App.vue +++ b/quiz-app/src/App.vue @@ -9,6 +9,7 @@ +
diff --git a/quiz-app/src/assets/translations/index.js b/quiz-app/src/assets/translations/index.js index ace2dc54..c9ed38a0 100644 --- a/quiz-app/src/assets/translations/index.js +++ b/quiz-app/src/assets/translations/index.js @@ -5,6 +5,7 @@ import id from './id.json'; import hi from './hi.json'; import it from './it.json'; import ja from './ja.json'; +import zh-tw from './zh-tw.json'; //export const defaultLocale = 'en'; @@ -15,6 +16,7 @@ const messages = { hi: hi[0], it: it[0], ja: ja[0], + zh-tw: zh-tw[0], }; export default messages; diff --git a/quiz-app/src/assets/translations/zh-tw.json b/quiz-app/src/assets/translations/zh-tw.json new file mode 100644 index 00000000..0d026ccd --- /dev/null +++ b/quiz-app/src/assets/translations/zh-tw.json @@ -0,0 +1,2509 @@ +[ + { + "title": "給初學者的網頁開發:小測驗", + "complete": "恭喜,您完成了所有試題!", + "error": "抱歉。請稍後再試。」", + "quizzes": [ + { + "id": 1, + "title": "課程一 - 程式語言簡介:課前測驗", + "quiz": [ + { + "questionText": "開發人員可在不編寫程式碼的情況下產生程式。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "低階語言常被使用在:", + "answerOptions": [ + { + "answerText": "網頁", + "isCorrect": "false" + }, + { + "answerText": "硬體", + "isCorrect": "true" + }, + { + "answerText": "遊戲軟體", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者工具會出現在網頁開發的環境中?", + "answerOptions": [ + { + "answerText": "硬體,如樹莓派", + "isCorrect": "false" + }, + { + "answerText": "瀏覽器開發工具", + "isCorrect": "true" + }, + { + "answerText": "作業系統相關文件", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 2, + "title": "課程一 - 程式語言簡介:課後測驗", + "quiz": [ + { + "questionText": "下列何者程式語言比較適合用來撰寫網頁?", + "answerOptions": [ + { + "answerText": "機器語言", + "isCorrect": "false" + }, + { + "answerText": "JavaScript", + "isCorrect": "true" + }, + { + "answerText": "Bash", + "isCorrect": "false" + } + ] + }, + { + "questionText": "每一位開發人員的開發環境都不盡相同。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "開發人員會如何修正錯誤的程式碼?", + "answerOptions": [ + { + "answerText": "語法凸顯", + "isCorrect": "false" + }, + { + "answerText": "偵錯", + "isCorrect": "true" + }, + { + "answerText": "程式碼格式化", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 3, + "title": "課程二 - GitHub簡介:課前測驗", + "quiz": [ + { + "questionText": "下列何種指令可以建立 Git 數據庫?", + "answerOptions": [ + { + "answerText": "git create", + "isCorrect": "false" + }, + { + "answerText": "git start", + "isCorrect": "false" + }, + { + "answerText": "git init", + "isCorrect": "true" + } + ] + }, + { + "questionText": "指令 git add 的目的為何?", + "answerOptions": [ + { + "answerText": "提交程式碼。", + "isCorrect": "false" + }, + { + "answerText": "加入檔案至索引成追蹤對象。", + "isCorrect": "true" + }, + { + "answerText": "加入檔案至GitHub。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何確認電腦內是否有安裝git?", + "answerOptions": [ + { + "answerText": "輸入 git --version", + "isCorrect": "true" + }, + { + "answerText": "輸入 git --installed", + "isCorrect": "false" + }, + { + "answerText": "輸入 git --init", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 4, + "title": "課程二 - GitHub簡介:課後測驗", + "quiz": [ + { + "questionText": "下列何者能確認同一分支內不同的審查、評論、測試……等?", + "answerOptions": [ + { + "answerText": "GitHub", + "isCorrect": "false" + }, + { + "answerText": "Pull Request", + "isCorrect": "true" + }, + { + "answerText": "Feature Branch", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何從雲端數據庫中取得所有的提交?", + "answerOptions": [ + { + "answerText": "git fetch", + "isCorrect": "false" + }, + { + "answerText": "git pull", + "isCorrect": "true" + }, + { + "answerText": "git commits -r", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何切換分支?", + "answerOptions": [ + { + "answerText": "git switch [branch-name]", + "isCorrect": "false" + }, + { + "answerText": "git checkout [branch-name]", + "isCorrect": "true" + }, + { + "answerText": "git load [branch-name]", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 5, + "title": "課程三 - 建立無障礙網頁:課前測驗", + "quiz": [ + { + "questionText": "下列何種工具可以確認網頁的無障礙性?", + "answerOptions": [ + { + "answerText": "Lighthouse", + "isCorrect": "true" + }, + { + "answerText": "Deckhouse", + "isCorrect": "false" + }, + { + "answerText": "Cleanhouse", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有實體的螢幕報讀器才能對視覺障礙者測試網頁親和力。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "網頁親和力只在公家機關的網頁才有需求。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 6, + "title": "課程三 - 建立無障礙網頁:課後測驗", + "quiz": [ + { + "questionText": "Lighthouse 只能檢查網頁親和力。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Color-safe 色彩工具可以幫助到:", + "answerOptions": [ + { + "answerText": "色盲", + "isCorrect": "false" + }, + { + "answerText": "視覺障礙者", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "描述性連結是無障礙網頁中重要的部分。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 7, + "title": "課程四 - JavaScript 基礎 - 資料類態:課前測驗", + "quiz": [ + { + "questionText": "布林值是檢查字串的長度的資料型態。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "下列何種行為可以用在字串上?", + "answerOptions": [ + { + "answerText": "合併", + "isCorrect": "true" + }, + { + "answerText": "串接", + "isCorrect": "false" + }, + { + "answerText": "拼接", + "isCorrect": "false" + } + ] + }, + { + "questionText": "== 和 === 是可互換的。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 8, + "title": "課程四 - JavaScript 基礎 - 資料類態:課後測驗", + "quiz": [ + { + "questionText": "常數與 let 和 var 宣告的變數相同,除了:", + "answerOptions": [ + { + "answerText": "常數必須要初始化。", + "isCorrect": "true" + }, + { + "answerText": "常數可以被修改。", + "isCorrect": "false" + }, + { + "answerText": "常數可以被重新賦值。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,負責處理數值型態資料的為 Numbers 與:", + "answerOptions": [ + { + "answerText": "bigint", + "isCorrect": "true" + }, + { + "answerText": "boolean", + "isCorrect": "false" + }, + { + "answerText": "star", + "isCorrect": "false" + } + ] + }, + { + "questionText": "字串值可以被單引號與雙引號所包住。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 9, + "title": "課程五 - JavaScript 基礎 - 函式與方法:課前測驗", + "quiz": [ + { + "questionText": "什麼是引數物件?", + "answerOptions": [ + { + "answerText": "用來宣告函式的定義。", + "isCorrect": "false" + }, + { + "answerText": "用來呼叫函式。", + "isCorrect": "true" + }, + { + "answerText": "用來與熟識的人共同持有。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "函式必須要有回傳值。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以隨意命名函式的名稱。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "是,但以可描述性的名稱為佳。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 10, + "title": "課程五 - JavaScript 基礎 - 函式與方法:課後測驗", + "quiz": [ + { + "questionText": "引數物件必須提供函式需要的所有參數。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "預設值(Default Value)的目的為何?", + "answerOptions": [ + { + "answerText": "設定正確的數值。", + "isCorrect": "false" + }, + { + "answerText": "參數的初始值,當忽略引數時,程式碼仍可運作。", + "isCorrect": "true" + }, + { + "answerText": "沒有意義。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "箭頭函式(fat arrow functions)允許開發人員:", + "answerOptions": [ + { + "answerText": "建立很重(heavy)的函式。", + "isCorrect": "false" + }, + { + "answerText": "可以忽略部分的函式名稱。", + "isCorrect": "true" + }, + { + "answerText": "建立匿名函式。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 11, + "title": "課程六 - JavaScript 基礎 - 在代碼中做出決定:課前測驗", + "quiz": [ + { + "questionText": "運算子 == 的運算為:", + "answerOptions": [ + { + "answerText": "相等", + "isCorrect": "true" + }, + { + "answerText": "嚴格相等", + "isCorrect": "false" + }, + { + "answerText": "賦值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,比較式後回傳的資料型態為?", + "answerOptions": [ + { + "answerText": "布林值", + "isCorrect": "true" + }, + { + "answerText": "空值", + "isCorrect": "false" + }, + { + "answerText": "字串", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,符號 ! 代表:", + "answerOptions": [ + { + "answerText": "邏輯否定", + "isCorrect": "true" + }, + { + "answerText": "重要的", + "isCorrect": "false" + }, + { + "answerText": "等於", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 12, + "title": "課程六 - JavaScript 基礎 - 在代碼中做出決定:課後測驗", + "quiz": [ + { + "questionText": "條件式 '1' == 1 會回傳下列何種結果?", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "空值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "條件式 '1' == 1 會回傳下列何種結果?", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + }, + { + "answerText": "空值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者為正確的邏輯「或」表示方法?", + "answerOptions": [ + { + "answerText": "a | b", + "isCorrect": "false" + }, + { + "answerText": "a || b", + "isCorrect": "true" + }, + { + "answerText": "a or b", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 13, + "title": "課程七 - JavaScript 基礎 - 矩陣與迴圈:課前測驗", + "quiz": [ + { + "questionText": "如果要提出矩陣中特定的元素,必須使用:", + "answerOptions": [ + { + "answerText": "中括號 []", + "isCorrect": "false" + }, + { + "answerText": "索引", + "isCorrect": "true" + }, + { + "answerText": "大括號 {}", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何取得矩陣內的元素個數?", + "answerOptions": [ + { + "answerText": "len(array)", + "isCorrect": "false" + }, + { + "answerText": "矩陣的屬性大小(Property Size)。", + "isCorrect": "false" + }, + { + "answerText": "矩陣的屬性長度(Property Length)。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在 JavaScript 中,索引從何數開始計算?", + "answerOptions": [ + { + "answerText": "0", + "isCorrect": "true" + }, + { + "answerText": "1", + "isCorrect": "false" + }, + { + "answerText": "2", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 14, + "title": "課程七 - JavaScript 基礎 - 矩陣與迴圈:課後測驗", + "quiz": [ + { + "questionText": "在 for-loop 迴圈中,需要修改何處來增加迭代次數到5次?", + "answerOptions": [ + { + "answerText": "條件式", + "isCorrect": "true" + }, + { + "answerText": "計數器", + "isCorrect": "false" + }, + { + "answerText": "迭代陳述式", + "isCorrect": "false" + } + ] + }, + { + "questionText": "while 迴圈與 for-loop 迴圈的差異在於:", + "answerOptions": [ + { + "answerText": "for-loop 迴圈需要計數器與迭代陳述式,while 迴圈只需要條件式。", + "isCorrect": "true" + }, + { + "answerText": "while 迴圈需要計數器與迭代陳述式,for-loop 迴圈只需要條件式。", + "isCorrect": "false" + }, + { + "answerText": "它們是一樣的,只是另一種稱呼而已。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "迴圈 (let i=1; i < 5; i++)中,會執行多少次迭代??", + "answerOptions": [ + { + "answerText": "5", + "isCorrect": "false" + }, + { + "answerText": "4", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 15, + "title": "課程八 - Terrarium 專案 - HTML簡介:課前測驗", + "quiz": [ + { + "questionText": "HTML 的全名為 HyperText Mockup Language。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "所有的 HTML 標籤都需要起始標籤與結束標籤。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "使用語意標籤最重要的應用為:", + "answerOptions": [ + { + "answerText": "方便程式碼的閱讀。", + "isCorrect": "false" + }, + { + "answerText": "螢幕閱讀器。", + "isCorrect": "true" + }, + { + "answerText": "管理用途。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 16, + "title": "課程八 - Terrarium 專案 - HTML簡介:課後測驗", + "quiz": [ + { + "questionText": "Spans 與 Divs 可以互相替換。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "HTML文件的標頭可以包含:", + "answerOptions": [ + { + "answerText": "標題標籤(title tag)", + "isCorrect": "false" + }, + { + "answerText": "元資訊(metadata)", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "開發人員無法使用不推薦使用的標籤。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但它們有被否決的充分理由。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 17, + "title": "課程九 - Terrarium 專案 - CSS簡介:課前測驗", + "quiz": [ + { + "questionText": "HTML 元素必須包含 class 或 id 才能被造型化。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS 全名為 Complete Style Sheets。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以利用 CSS 來建立動畫。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 18, + "title": "課程九 - Terrarium 專案 - CSS簡介:課後測驗", + "quiz": [ + { + "questionText": "CSS 可以被撰寫在 HTML 檔案的開頭。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "CSS 在應用程式中是必須的物件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但如果想讓畫面變美觀就需要使用CSS。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以利用下列何者瀏覽器工具來檢查 CSS?", + "answerOptions": [ + { + "answerText": "Elements", + "isCorrect": "false" + }, + { + "answerText": "Styles", + "isCorrect": "true" + }, + { + "answerText": "Network", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 19, + "title": "課程十 - Terrarium 專案 - DOM 元素控制與閉包:課前測驗", + "quiz": [ + { + "questionText": "DOM 元素全名為 Document Object Management", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以將 DOM 元素理解為樹的一種。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "利用 Web API,開發人員就能控制 DOM 元素。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 20, + "title": "課程十 - Terrarium 專案 - DOM 元素控制與閉包:課後測驗", + "quiz": [ + { + "questionText": "DOM 元素是表現網頁文件的一種物件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用 JavaScript 閉包可以達成:", + "answerOptions": [ + { + "answerText": "在函式中撰寫函式。", + "isCorrect": "true" + }, + { + "answerText": "將 DOM 元素包住。", + "isCorrect": "false" + }, + { + "answerText": "關閉腳本區。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用閉包可以在單一或多個函式中存取外部函式的 _________。", + "answerOptions": [ + { + "answerText": "矩陣", + "isCorrect": "false" + }, + { + "answerText": "作用域", + "isCorrect": "true" + }, + { + "answerText": "函式", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 21, + "title": "課程十一 - 打字遊戲:課前測驗", + "quiz": [ + { + "questionText": "事件驅動程式發生在使用者:", + "answerOptions": [ + { + "answerText": "按下按鈕。", + "isCorrect": "false" + }, + { + "answerText": "改變數值。", + "isCorrect": "false" + }, + { + "answerText": "與網頁作互動。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在程序式程式中,函式會以下列方式被呼叫。", + "answerOptions": [ + { + "answerText": "在任何時刻中。", + "isCorrect": "false" + }, + { + "answerText": "在特定的順序中。", + "isCorrect": "true" + }, + { + "answerText": "由左至右。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 DOM 中最常用來建立事件處理的方法為:", + "answerOptions": [ + { + "answerText": "addEventListener", + "isCorrect": "true" + }, + { + "answerText": "addListener", + "isCorrect": "false" + }, + { + "answerText": "addEvent", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 22, + "title": "課程十一 - 打字遊戲:課後測驗", + "quiz": [ + { + "questionText": "使用者做的大部分網頁互動都會觸發事件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "常見的事件包括:", + "answerOptions": [ + { + "answerText": "click_event", + "isCorrect": "false" + }, + { + "answerText": "select_event", + "isCorrect": "false" + }, + { + "answerText": "input_event", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以使用匿名函式來建立事件處理。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 23, + "title": "課程十二 - 瀏覽器擴充功能專案 - 關於瀏覽器:課前測驗", + "quiz": [ + { + "questionText": "使用者可以從下列管道取得瀏覽器擴充功能:", + "answerOptions": [ + { + "answerText": "沃爾瑪(WalMart)", + "isCorrect": "false" + }, + { + "answerText": "瀏覽器擴充商店", + "isCorrect": "true" + }, + { + "answerText": "應用程式商店", + "isCorrect": "false" + } + ] + }, + { + "questionText": "NPM 全名為", + "answerOptions": [ + { + "answerText": "Node Package Manager", + "isCorrect": "true" + }, + { + "answerText": "Netscape Primary Mix", + "isCorrect": "false" + }, + { + "answerText": "Natural Processing Manager", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器可以安全地或非安全地提供網頁服務。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 24, + "title": "課程十二 - 瀏覽器擴充功能專案 - 關於瀏覽器:課後測驗", + "quiz": [ + { + "questionText": "網際網路的發明者為:", + "answerOptions": [ + { + "answerText": "Tom Barnard-Loft", + "isCorrect": "false" + }, + { + "answerText": "Tim Berners-Lee", + "isCorrect": "true" + }, + { + "answerText": "Trish Berth-Pool", + "isCorrect": "false" + } + ] + }, + { + "questionText": "第一款網頁瀏覽器為:", + "answerOptions": [ + { + "answerText": "WorldWideWeb", + "isCorrect": "true" + }, + { + "answerText": "Mozilla", + "isCorrect": "false" + }, + { + "answerText": "Netscape", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器可以儲存使用者上網的歷史紀錄。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 25, + "title": "課程十三 - 瀏覽器擴充功能專案 - 呼叫API、使用Local Storage:課前測驗", + "quiz": [ + { + "questionText": "APIs 全名為", + "answerOptions": [ + { + "answerText": "Application Programming Interfaces", + "isCorrect": "true" + }, + { + "answerText": "A Programming Inference", + "isCorrect": "false" + }, + { + "answerText": "Anti Proven Intentions", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用API能與 _________ 做互動。", + "answerOptions": [ + { + "answerText": "網路上的一項資產", + "isCorrect": "false" + }, + { + "answerText": "資料庫", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "任何人都可以建立 API。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 26, + "title": "課程十三 - 瀏覽器擴充功能專案 - 呼叫API、使用Local Storage:課後測驗", + "quiz": [ + { + "questionText": "當使用者關閉瀏覽器視窗時,LocalStorage 會被清除。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "主要瀏覽器視窗會管理擴充功能的LocalStorage使用情形。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在API context中,REST 全名為", + "answerOptions": [ + { + "answerText": "Representational State Transfer", + "isCorrect": "true" + }, + { + "answerText": "Returning State Tasks", + "isCorrect": "false" + }, + { + "answerText": "Rendering State To Browser", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 27, + "title": "課程十四 - 瀏覽器擴充功能專案 - 學習背景工作與效能:課前測驗", + "quiz": [ + { + "questionText": "使用者可以利用下列何種方式測試應用程式的效能?", + "answerOptions": [ + { + "answerText": "瀏覽器工具", + "isCorrect": "true" + }, + { + "answerText": "獨立軟體包", + "isCorrect": "false" + }, + { + "answerText": "手動測試", + "isCorrect": "false" + } + ] + }, + { + "questionText": "通常網頁的效能代表:", + "answerOptions": [ + { + "answerText": "多快可以載入完成。", + "isCorrect": "false" + }, + { + "answerText": "程式執行的速率有多快。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "總體來說,在這幾年間網頁的「負擔」:", + "answerOptions": [ + { + "answerText": "變輕了。", + "isCorrect": "false" + }, + { + "answerText": "變重了。", + "isCorrect": "true" + }, + { + "answerText": "維持原樣。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 28, + "title": "課程十四 - 瀏覽器擴充功能專案 - 學習背景工作與效能:課後測驗", + "quiz": [ + { + "questionText": "為了取得更好的網頁效能,清除快取並重新載入效能分析器是一種方法。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器擴充功能是固有的功能。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "分析下列地方來尋找效能的瓶頸:", + "answerOptions": [ + { + "answerText": "DOM 查找元素。", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 最佳化。", + "isCorrect": "false" + }, + { + "answerText": "資產管理。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 29, + "title": "課程十五 - 太空遊戲 - 介紹:課前測驗", + "quiz": [ + { + "questionText": "JavaScript 是不常見的遊戲開發程式語言。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "發布/訂閱是管理遊戲資產與流程的合理規範。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "類別與組合可以處理物件繼承的概念。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 30, + "title": "課程十五 - 太空遊戲 - 介紹:課後測驗", + "quiz": [ + { + "questionText": "依賴物件繼承的類別可以歸咎於其行為。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "組合是處理遊戲物件最好的設計模式。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Pub/Sub 代表的是:", + "answerOptions": [ + { + "answerText": "Publish/Subscribe", + "isCorrect": "true" + }, + { + "answerText": "Print/Staple", + "isCorrect": "false" + }, + { + "answerText": "Publish/Sanitize", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 31, + "title": "課程十六 - 太空遊戲 - 繪製英雄怪物於畫布:課前測驗", + "quiz": [ + { + "questionText": "你可以利用Canvas元素在螢幕上繪製圖案。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Canvas API只能畫出簡單的幾何圖形。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "座標點(0,0)代表Canvas左下方。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 32, + "title": "課程十六 - 太空遊戲 - 繪製英雄怪物於畫布:課後測驗", + "quiz": [ + { + "questionText": "繪圖處理能直接應用在Canvas上。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "藉由監測讀取事件來得知非同步的圖片是否被載入完成。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "繪製圖片到螢幕的指令為:", + "answerOptions": [ + { + "answerText": "paintImage()", + "isCorrect": "false" + }, + { + "answerText": "drawImage()", + "isCorrect": "true" + }, + { + "answerText": "draw()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 33, + "title": "課程十七 - 太空遊戲 - 加入律動:課前測驗", + "quiz": [ + { + "questionText": "任何物件可以接收鍵盤事件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "鍵盤事件與滑鼠事件是相同的監聽方法。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "若想讓事情定期的觸發,需要用到什麼函式?", + "answerOptions": [ + { + "answerText": "setInterval()", + "isCorrect": "true" + }, + { + "answerText": "setTimeout()", + "isCorrect": "false" + }, + { + "answerText": "sleep()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 34, + "title": "課程十七 - 太空遊戲 - 加入律動:課後測驗", + "quiz": [ + { + "questionText": "更新螢幕一定要全部重新繪製。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "什麼是遊戲迴圈?", + "answerOptions": [ + { + "answerText": "函式確保遊戲能重新開始。", + "isCorrect": "false" + }, + { + "answerText": "函式決定遊戲的運作時速。", + "isCorrect": "false" + }, + { + "answerText": "函式確保定期事件發生並將畫面呈獻給玩家。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "重新繪製螢幕的時機點為:", + "answerOptions": [ + { + "answerText": "玩家產生互動。", + "isCorrect": "false" + }, + { + "answerText": "有東西移動。", + "isCorrect": "true" + }, + { + "answerText": "時間的推移。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 35, + "title": "課程十八 - 太空遊戲 - 加入雷射與碰撞偵測:課前測驗", + "quiz": [ + { + "questionText": "碰撞偵測是偵測兩物體是否發生碰撞。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何將成員從螢幕中移除?", + "answerOptions": [ + { + "answerText": "呼叫垃圾清潔員。", + "isCorrect": "false" + }, + { + "answerText": "標記為陣亡,在下一個繪製週期只畫存活的成員。", + "isCorrect": "true" + }, + { + "answerText": "將成員移動到其他象限。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中模擬雷射最合適的方式為:", + "answerOptions": [ + { + "answerText": "根據鍵盤事件建立可視物件。", + "isCorrect": "true" + }, + { + "answerText": "建立動態圖像。", + "isCorrect": "false" + }, + { + "answerText": "讓敵人定期地爆炸。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 36, + "title": "課程十八 - 太空遊戲 - 加入雷射與碰撞偵測:課後測驗", + "quiz": [ + { + "questionText": "在碰撞偵測中,需要判斷兩者:", + "answerOptions": [ + { + "answerText": "圓圈內是否有所相交。", + "isCorrect": "false" + }, + { + "answerText": "矩形內是否有所相交。", + "isCorrect": "true" + }, + { + "answerText": "兩點之間的距離。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "建立無敵時間的目的為:", + "answerOptions": [ + { + "answerText": "讓遊戲變得更難,讓玩家無法重複擊發雷射摧毀敵人。", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 在單位時間內只能處理一定額度的事件,需要有所限制。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "常數在程式碼中是醒目的原因為:", + "answerOptions": [ + { + "answerText": "它們以全大寫書寫。", + "isCorrect": "true" + }, + { + "answerText": "它們有特定的名稱。", + "isCorrect": "false" + }, + { + "answerText": "它們用特定字元,連接。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 37, + "title": "課程十九 - 太空遊戲 - 分數與生命數:課前測驗", + "quiz": [ + { + "questionText": "如何利用Canvas元素在畫面上寫字?", + "answerOptions": [ + { + "answerText": "將文字包在div或span元素中。", + "isCorrect": "false" + }, + { + "answerText": "呼叫 drawText()在Canvas元素上。", + "isCorrect": "false" + }, + { + "answerText": "Call fillText() on the context object", + "isCorrect": "true" + } + ] + }, + { + "questionText": "為什麼遊戲需要有「生命數」的概念?", + "answerOptions": [ + { + "answerText": "為了表現玩家還能承受多少攻擊。", + "isCorrect": "false" + }, + { + "answerText": "為了讓遊戲不會直接結束,允許玩家有容錯空間。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "改變 Canvas 元素上字的顏色可以利用:", + "answerOptions": [ + { + "answerText": "fillColor", + "isCorrect": "false" + }, + { + "answerText": "fillStyle", + "isCorrect": "true" + }, + { + "answerText": "textAlign", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 38, + "title": "課程十九 - 太空遊戲 - 分數與生命數:課後測驗", + "quiz": [ + { + "questionText": "如何有趣地表現出玩家剩餘的生命數?", + "answerOptions": [ + { + "answerText": "剩餘艦艇的數字。", + "isCorrect": "false" + }, + { + "answerText": "得點系統。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "如何讓畫面裡 Canvas 元素上的文字置中?", + "answerOptions": [ + { + "answerText": "利用 Flexbox。", + "isCorrect": "false" + }, + { + "answerText": "讓文字的 x 座標點為玩家視窗寬度的一半。", + "isCorrect": "true" + }, + { + "answerText": "設定文字內容的 textAlign 屬性為中間。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在程式碼中,用下列何者表示扣除一條性命?", + "answerOptions": [ + { + "answerText": "this.life-", + "isCorrect": "false" + }, + { + "answerText": "this.life--", + "isCorrect": "true" + }, + { + "answerText": "this.life++", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 39, + "title": "課程二十 - 太空遊戲 - 結束與重來:課前測驗", + "quiz": [ + { + "questionText": "何時為重新遊戲的最好時機?", + "answerOptions": [ + { + "answerText": "當玩家勝利或落敗時。", + "isCorrect": "true" + }, + { + "answerText": "任一時刻。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "什麼時候該讓遊戲結束?", + "answerOptions": [ + { + "answerText": "當單一敵人艦艇遭到擊毀。", + "isCorrect": "false" + }, + { + "answerText": "當玩家艦艇遭到擊毀。", + "isCorrect": "true" + }, + { + "answerText": "當分數進帳。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "最適合加入新關卡到遊戲的方式為:", + "answerOptions": [ + { + "answerText": "增加通關要求的分數門檻。", + "isCorrect": "true" + }, + { + "answerText": "增加更多的玩家。", + "isCorrect": "false" + }, + { + "answerText": "增加更好的圖像。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 40, + "title": "課程二十 - 太空遊戲 - 結束與重來:課後測驗", + "quiz": [ + { + "questionText": "當遊戲結束時,下列何者為合適的事件?", + "answerOptions": [ + { + "answerText": "顯示適當的訊息。", + "isCorrect": "false" + }, + { + "answerText": "結束遊戲。", + "isCorrect": "false" + }, + { + "answerText": "顯示適當的訊息,詢問玩家是否重來,顯示對應的選項按鈕。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有當遊戲結束時才能重新遊戲。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "當遊戲結束時,何種時機清除 EventEmitter 較為合適?", + "answerOptions": [ + { + "answerText": "清除完事件監聽者。", + "isCorrect": "true" + }, + { + "answerText": "清除完畫面。", + "isCorrect": "false" + }, + { + "answerText": "關閉遊戲視窗。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 41, + "title": "課程二十一 - 銀行專案 - HTML模板與網路連線App:課前測驗", + "quiz": [ + { + "questionText": "一個網路程式必須要有多個HTML檔才能呈現不同頁面。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "網路程式允許用戶在本地儲存資料", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "什麼是網路程式資料供應者最合適的方式?", + "answerOptions": [ + { + "answerText": "一個本地資料庫。", + "isCorrect": "false" + }, + { + "answerText": "一個 JavaScript 物件。", + "isCorrect": "false" + }, + { + "answerText": "一個含有 JSON API 的伺服器。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 42, + "title": "課程二十一 - 銀行專案 - HTML模板與網路連線App:課後測驗", + "quiz": [ + { + "questionText": "HTML 模板在預設中是 DOM 元素的一部份。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "哪個 URL 部分需要被使用在路由上?", + "answerOptions": [ + { + "answerText": "window.location.pathname", + "isCorrect": "false" + }, + { + "answerText": "window.location.origin", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "當呼叫 history.pushState() 函式時,下列何者事件會被觸發?", + "answerOptions": [ + { + "answerText": "pushstate", + "isCorrect": "false" + }, + { + "answerText": "popstate", + "isCorrect": "true" + }, + { + "answerText": "navigate", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 43, + "title": "課程二十二 - 銀行專案 - 登入與註冊表單:課前測驗", + "quiz": [ + { + "questionText": "HTML 表單允許用戶不須利用 JavaScript 輸入資料到伺服器。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "
` 之前: + +```html +
+
+
+
+
+
+
+
+
+``` + +✅ 即使你在檔案中新增了程式碼,你卻沒看到任何東西。為什麼? + +--- + +## 🚀 挑戰 + +這邊有一些「古老」的 HTML 標籤。雖然[這些標籤](https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Obsolete_and_deprecated_elements)被歸為不推薦使用的標籤,但仍值得去嘗試的。你可以用 `` 標籤來讓 h1 標題文字變成縱向呈現嗎?實驗完後,記得要移除這些標籤喔。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16) + +## 複習與自學 + +HTML 是一種「行之有效」的構築系統,建立了現今的各種網頁。從標籤來學習關於 HTML 的歷史,你能了解為什麼有的標籤被排除,而有的被新增上去嗎?有什麼標籤會在未來被建立上去呢? + +學習更多關於建立網頁的資訊:[Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-13441-cxa)。 + + +## 作業 + +[練習 HTML:建立部落格雛形](assignment.zh-tw.md) diff --git a/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md b/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md new file mode 100644 index 00000000..59e5df2c --- /dev/null +++ b/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 練習 HTML:建立部落格雛形 + +## 簡介 + +想像你正在設計,或重新設計你自己的專屬網頁。建立網頁的圖像設計雛形,並用 HTML 語法建立這些網頁元素。你可以建在紙上並掃描它,或者是建在軟體中,只要確保有 HTML 語法在裡面。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ----------------------- ------------ | ------------------------------- | --------------------------------- | +| | 可以見到部落格編排包含10種以上的元素 | 見到部落格編排大約有 5 種的元素 | 見到部落格編排最多只有 3 種的元素 | \ No newline at end of file diff --git a/quiz-app/src/assets/translations/zh-tw.json b/quiz-app/src/assets/translations/zh-tw.json index 93065430..1ed055cb 100644 --- a/quiz-app/src/assets/translations/zh-tw.json +++ b/quiz-app/src/assets/translations/zh-tw.json @@ -756,7 +756,7 @@ }, { "id": 15, - "title": "課程八 - Terrarium 專案 - HTML簡介:課前測驗", + "title": "課程八 - Terrarium 專案 - HTML 簡介:課前測驗", "quiz": [ { "questionText": "HTML 的全名為 HyperText Mockup Language。", @@ -805,7 +805,7 @@ }, { "id": 16, - "title": "課程八 - Terrarium 專案 - HTML簡介:課後測驗", + "title": "課程八 - 盆栽盒專案 - HTML 簡介:課後測驗", "quiz": [ { "questionText": "Spans 與 Divs 可以互相替換。", @@ -821,7 +821,7 @@ ] }, { - "questionText": "HTML文件的標頭可以包含:", + "questionText": "HTML 文件的標頭可以包含:", "answerOptions": [ { "answerText": "標題標籤(title tag)", @@ -858,7 +858,7 @@ }, { "id": 17, - "title": "課程九 - Terrarium 專案 - CSS簡介:課前測驗", + "title": "課程九 - 盆栽盒專案 - CSS簡介:課前測驗", "quiz": [ { "questionText": "HTML 元素必須包含 class 或 id 才能被造型化。", @@ -903,7 +903,7 @@ }, { "id": 18, - "title": "課程九 - Terrarium 專案 - CSS簡介:課後測驗", + "title": "課程九 - 盆栽盒專案 - CSS簡介:課後測驗", "quiz": [ { "questionText": "CSS 可以被撰寫在 HTML 檔案的開頭。", @@ -956,7 +956,7 @@ }, { "id": 19, - "title": "課程十 - Terrarium 專案 - DOM 元素控制與閉包:課前測驗", + "title": "課程十 - 盆栽盒專案 - DOM 元素控制與閉包:課前測驗", "quiz": [ { "questionText": "DOM 元素全名為 Document Object Management", @@ -1001,7 +1001,7 @@ }, { "id": 20, - "title": "課程十 - Terrarium 專案 - DOM 元素控制與閉包:課後測驗", + "title": "課程十 - 盆栽盒專案 - DOM 元素控制與閉包:課後測驗", "quiz": [ { "questionText": "DOM 元素是表現網頁文件的一種物件。", From 2369ebf92c06101a62561cbd452233174fa68ddf Mon Sep 17 00:00:00 2001 From: CRTao Date: Tue, 23 Feb 2021 13:25:25 +0800 Subject: [PATCH 05/13] translate lesson 3 to zh-tw --- .../translations/README.zh-tw.md | 8 +- .../translations/README.zh-tw.md | 263 ++++++++++++++++++ .../translations/assignment.zh-tw.md | 11 + .../translations/README.zh-tw.md | 219 +++++++++++++++ .../translations/assignment.zh-tw.md | 11 + 3-terrarium/translations/README.zh-tw.md | 34 +++ quiz-app/src/assets/translations/zh-tw.json | 10 +- 7 files changed, 547 insertions(+), 9 deletions(-) create mode 100644 3-terrarium/2-intro-to-css/translations/README.zh-tw.md create mode 100644 3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md create mode 100644 3-terrarium/3-intro-to-DOM-and-closures/translations/README.zh-tw.md create mode 100644 3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.zh-tw.md create mode 100644 3-terrarium/translations/README.zh-tw.md diff --git a/3-terrarium/1-intro-to-html/translations/README.zh-tw.md b/3-terrarium/1-intro-to-html/translations/README.zh-tw.md index 8e1f5bfd..1a786854 100644 --- a/3-terrarium/1-intro-to-html/translations/README.zh-tw.md +++ b/3-terrarium/1-intro-to-html/translations/README.zh-tw.md @@ -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 - 歡迎來到我的虛擬盆栽盒 + Welcome to my Virtual Terrarium @@ -91,7 +91,7 @@ HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[ - 歡迎來到我的虛擬盆栽盒 + Welcome to my Virtual Terrarium @@ -180,7 +180,7 @@ HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[ 新增下列程式碼到你的 `` 標籤中: ```html -

我的盆栽盒

+

My Terrarium

``` 使用語義化標籤如:標題 `

` 和未排序串列 `
    ` ,能幫助螢幕報讀器理解網頁的內容。普遍來說,按鈕為 ` + + + + +``` + +### 執行應用程式 + +最好的逐段開發模式是定期的確認程式結果。讓我們來執行現在的應用程式。Visual Studio Code 上有一個好用的擴充套件為[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer),它會在你儲存網頁檔案時,同時架設並更新瀏覽器上的網頁。 + +- 安裝[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer),點擊連結中的 **Install** + - 瀏覽器要求開啟 Visual Studio Code,Visual Studio Code 會執行後續的安裝流程 + - 安裝完後,重啟 Visual Studio Code +- 一旦安裝完成,在 Visual Studio Code 下按下 Ctrl-Shift-P (或 Cmd-Shift-P) 開啟指令視窗。 +- 輸入 **Live Server: Open with Live Server** + - Live Server 會架設並發布你的網頁成果 +- 開啟瀏覽器,前往 **https://localhost:5500** +- 現在你能看到你所做的網頁! + +讓我們來為網頁增加更多功能。 + +## 加入 CSS + +建立完 HTML 檔,現在我們為了造型加入 CSS。我們需要標記玩家需要輸入的單字,若單字輸入錯誤時需要改變文字框的顏色。利用兩組 class 來完成: + +在檔案 **style.css** 加入下列語法: + +```css +/* 在 style.css 中 */ +.highlight { + background-color: yellow; +} + +.error { + background-color: lightcoral; + border: red; +} +``` + +✅ 處理 CSS 時,你可以規劃任何你想要的介面布局。花點時間讓你的網頁更迷人: + +- 變更其他字型 +- 改變標題顏色 +- 改變物件大小 + +## JavaScript + +建立完使用者介面後,我們要專注在 JavaScript 上,提供網頁邏輯處理的能力。我們將工作分為下列步驟: + +- [建立常數](#建立常數) +- [事件監聽者 - 開始遊戲](#加入開始邏輯) +- [事件監聽者 - 輸入文字](#加入打字邏輯) + +首先,我們先編輯檔案 **script.js**。 + +### 建立常數 + +加入一些變數給程式使用。同樣地,就像食譜一樣,我們需要的食材如下: + +- 矩陣,儲存所有引文 +- 空矩陣,儲存單一引文的所有單字 +- 變數,儲存空矩陣的索引,標記玩家現在面對的單字 +- 變數,紀錄玩家點擊開始時的時間 + +我們也需要將使用者介面上的物件做連結: + +- 文字框 (**typed-value**) +- 顯示引文 (**quote**) +- 訊息欄 (**message**) + +```javascript +// 在檔案 script.js 中 +// 所有的引文內容 +const quotes = [ + 'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.', + 'There is nothing more deceptive than an obvious fact.', + 'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.', + 'I never make exceptions. An exception disproves the rule.', + 'What one man can invent another can discover.', + 'Nothing clears up a case so much as stating it to another person.', + 'Education never ends, Watson. It is a series of lessons, with the greatest for the last.', +]; +// 儲存單字列表及目前要輸入的單字索引 +let words = []; +let wordIndex = 0; +// 開始時間 +let startTime = Date.now(); +// 網頁物件連結 +const quoteElement = document.getElementById('quote'); +const messageElement = document.getElementById('message'); +const typedValueElement = document.getElementById('typed-value'); +``` + +✅ 試著加入更多的引文到你的遊戲中。 + +> **筆記** 我們可以接收任何物件,只要使用程式碼 `document.getElementById`。因為我們需要定期參考這些元素,所以使用常數來確認是否有單字輸入錯誤的問題。框架如[Vue.js](https://vuejs.org/)或[React](https://reactjs.org/)可以幫助你更好管理你的程式碼。 + +花點時間觀看下列關於 `const`、`let` 與 `var` 的影片。 + +[![變數類型](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "變數類型") + +> 點擊上方圖片以觀賞關於變數的影片。 + +### 加入開始邏輯 + +為了開始我們的遊戲,玩家會點擊開始按鈕。當然,我們不知道何時玩家會開始遊戲,這就是為什麼我們使用[事件監聽者](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)到程式中。一個事件監聽者允許我們監看事件的觸發與對應的回應程式。在這個例子,我們希望當使用者點擊開始時,執行某些程式。 + +當玩家點擊 **start** 按鈕後,我們需要挑選一段引文、設定使用者介面並追蹤現在玩家的要輸入的單字與時間。下列為我們需要新增的程式碼,我們會在之後逐行解釋。 + +```javascript +// 在 script.js 末端 +document.getElementById('start').addEventListener('click', () => { + // 取得一行引文 + const quoteIndex = Math.floor(Math.random() * quotes.length); + const quote = quotes[quoteIndex]; + // 將引文分成許多單字,存在矩陣中。 + words = quote.split(' '); + // 重制單字索引來做追蹤 + wordIndex = 0; + + // 更新使用者介面 + // 建立 span 元素的矩陣,設定 class 用。 + const spanWords = words.map(function(word) { return `${word} `}); + // 轉換成字串並以 innerHTML 顯示引文 + quoteElement.innerHTML = spanWords.join(''); + // 標記第一個單字 + quoteElement.childNodes[0].className = 'highlight'; + // 清除訊息欄之前的訊息 + messageElement.innerText = ''; + + // 設定文字框 + // 清除文字框 + typedValueElement.value = ''; + // 設定 focus + typedValueElement.focus(); + // 設定事件驅動程式 + + // 開始計時器 + startTime = new Date().getTime(); +}); +``` + +我們來分解程式碼吧! + +- 設定單字追蹤 + - 使用[Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor)和[Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random)讓我們能隨機從矩陣 `quotes` 中挑選一行引文 + - 轉換 `quote` 成 `words` 組成的矩陣,追蹤目前玩家正在輸入的單字 + - `wordIndex` 設定為 0,玩家會從第一的單字開始輸入 +- 設定使用者介面 + - 建立矩陣 `spanWords`,將每一個單字包在 `span` 元素中 + - 這讓我們能高光標記單字 + - `join` 矩陣來建立字串,我們可以在 `quoteElement` 上更新 `innerHTML` + - 這會顯示引文給玩家檢視 + - 設定第一個 `span` 元素的 `className` 成 `highlight`,來標記單字呈黃色 + - 修改 `messageElement`的 `innerText` 成 `''`,這會清除訊息欄的內容 +- 設定文字框 + - 清除目前 `typedValueElement` 的 `value` + - 設定 `typedValueElement` 成 `focus` +- 呼叫 `getTime` 來啟始計時器 + +### 加入打字邏輯 + +當玩家開始打字時,`input` 事件會被觸發。對應的事件監聽者需要檢查玩家是否輸入正確的單字,監控目前的遊戲狀況。回到檔案 **script.js**,加入下方程式碼到檔案最下方。我們會在後續解釋程式碼。 + +```javascript +// script.js 最末端 +typedValueElement.addEventListener('input', () => { + // 取得目前的單字 + const currentWord = words[wordIndex]; + // 取得目前輸入的數值 + const typedValue = typedValueElement.value; + + if (typedValue === currentWord && wordIndex === words.length - 1) { + // 句子最末端 + // 顯示成功 + const elapsedTime = new Date().getTime() - startTime; + const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`; + messageElement.innerText = message; + } else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) { + // 單字最末端 + // 清除輸入的數值,準備給新的單字使用 + typedValueElement.value = ''; + // 移動到下一個單字 + wordIndex++; + // 重設所有引文子元素的 class 名稱 + for (const wordElement of quoteElement.childNodes) { + wordElement.className = ''; + } + // 標記新單字 + quoteElement.childNodes[wordIndex].className = 'highlight'; + } else if (currentWord.startsWith(typedValue)) { + // 單字目前輸入正確 + // 標記下一個單字 + typedValueElement.className = ''; + } else { + // 單字輸入錯誤 + typedValueElement.className = 'error'; + } +}); +``` + +讓我們分解程式碼吧!我們開始取得目前的單字與玩家輸入的數值。我們建立一系列的邏輯,檢查引文是否輸入完成,單字是否輸入完成,單字是否正確、是否錯誤。 + +- 引文完成,檢查 `typedValue` 與 `currentWord` 相等且 `wordIndex` 與 `words` 的 `length` 減一相等。 + - 計算 `elapsedTime` ,利用目前時間減去 `startTime` 取得遊戲時長 + - `elapsedTime` 除以 1,000 ,轉化毫秒單位為秒單位 + - 顯示成功訊息 +- 單字完成,以 `typedValue` 間的空白為界,檢查 `typedValue` 是否與 `currentWord` 相等 + - 設定 `typedElement` 的 `value` 成 `''` ,準備給下一個單字輸入進來 + - 增加 `wordIndex` 到下一個單字 + - 進迴圈,每一個 `quoteElement` 的 `childNodes` ,它們的 `className` 都被設為 `''` ,代表預設的單字呈現規則 + - 設定單字的 `className` 成 `highlight` 來標記為下一個被輸入的單字 +- 單字目前輸入正確但未完成,從 `typedValue` 開始檢查 `currentWord` + - 確保清除 `typedValueElement` 的 `className`,顯示預設的呈現方式。 +- 若此時輸入錯誤,我們加上錯誤規則 + - 設定 `typedValueElement` 的 `className` 成 `error` + +## 測試你的應用程式 + +我們做到最後了!最後一步就是確保我們的應用程式運作正常。試試看!不要擔心程式出現錯誤,**所有的開發者**都會面臨錯誤。有需要時,檢查程式訊息並偵錯。 + +點擊按鈕 **start**,馬上開始輸入單字!你可以看看這預覽動畫。 + +![遊戲中的動畫](../4-typing-game/images/demo.gif) + +--- + +## 🚀 挑戰 + +加入更多功能。 + +- 在完成遊戲時,關閉 `input` 事件監聽者;遊戲重新開始時,再重新開啟它。 +- 當玩家完成引文時,關閉文字框 +- 以對話窗格的方式顯示恭賀訊息 +- 利用[localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)儲存最高分的資料 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/22) + +## 複習與自學 + +在瀏覽器上閱讀[所有開發者可運用的事件](https://developer.mozilla.org/en-US/docs/Web/Events),想想你能在什麼樣的場合使用各個事件。 + +## 作業 + +[建立一款新的鍵盤遊戲](assignment.zh-tw.md) diff --git a/4-typing-game/typing-game/translations/assignment.zh-tw.md b/4-typing-game/typing-game/translations/assignment.zh-tw.md new file mode 100644 index 00000000..a85f9f8b --- /dev/null +++ b/4-typing-game/typing-game/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 建立一款新的鍵盤遊戲 + +## 簡介 + +建立一款使用鍵盤事件的小遊戲。它可以是不同的鍵盤輸入遊戲:使用鍵盤在視窗上繪製像素點的繪圖遊戲。激發你的創意吧! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ------------------ | ------------ | ------------ | +| | 呈現完整的遊戲內容 | 遊戲內容單調 | 遊戲出現問題 | From 8516e36f1be45e3cd5263eb129f30015df3ffc65 Mon Sep 17 00:00:00 2001 From: CRTao Date: Tue, 2 Mar 2021 15:30:09 +0800 Subject: [PATCH 07/13] translate lesson 5 to zh-tw --- .../translations/README.zh-tw.md | 167 +++++++++++++ .../translations/assignment.zh-tw.md | 11 + .../translations/README.zh-tw.md | 224 ++++++++++++++++++ .../translations/assignment.zh-tw.md | 11 + .../translations/README.zh.tw.md | 160 +++++++++++++ .../translations/assignment.zh-tw.md | 9 + .../translations/README.zh-tw.md | 28 +++ 7 files changed, 610 insertions(+) create mode 100644 5-browser-extension/1-about-browsers/translations/README.zh-tw.md create mode 100644 5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md create mode 100644 5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md create mode 100644 5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md create mode 100644 5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md create mode 100644 5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md create mode 100644 5-browser-extension/translations/README.zh-tw.md diff --git a/5-browser-extension/1-about-browsers/translations/README.zh-tw.md b/5-browser-extension/1-about-browsers/translations/README.zh-tw.md new file mode 100644 index 00000000..7b931577 --- /dev/null +++ b/5-browser-extension/1-about-browsers/translations/README.zh-tw.md @@ -0,0 +1,167 @@ +# 瀏覽器擴充功能專案 Part 1:關於瀏覽器 + +![瀏覽器繪圖筆記](../images/sketchnote.jpg) +> 由 [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) 繪製 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/23) + +### 大綱 + +瀏覽器擴充功能新增額外的功能給瀏覽器。在你建立之前,你應該學習瀏覽器是如何運作的。 + +### 關於瀏覽器 + +在這一系列的課程中,你會學習如何建立瀏覽器擴充功能,運作在 Chrome、Firefox 與 Edge 瀏覽器上。在這一章中,你會探索瀏覽器是如何運作,建立瀏覽器擴充功能的內容。 + +但到底何謂瀏覽器?它是幫助用戶顯示伺服器內容到網頁上的程式軟體。 + +✅ 小歷史:第一個網頁瀏覽器為 'WorldWideWeb',由 Timothy Berners-Lee 爵士於 1990 年建立。 + +![早期的瀏覽器](../images/earlybrowsers.jpg) +> 這邊有一些早期的瀏覽器,請參考[Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing) + +用戶使用網址 URL (Uniform Resource Locator) 位置連上網路,通常以 `http` 或 `https` 位置開頭使用超文本傳輸協定(Hypertext Transfer Protocol),瀏覽器便能與該伺服器溝通並抓取網頁的資料。 + +這時,瀏覽器轉譯引擎會呈現到用戶的裝置上,可以是手機、桌機或是筆記型電腦。 + +瀏覽器也有能力暫存內容,不需要每一次都向伺服器請求內容。瀏覽器儲存用戶的瀏覽紀錄、儲存 'cookies',一種包含用戶活動資訊的小型資料。 + +請記得一件重要的事,各家瀏覽器並不會相同!每一種瀏覽器都有各自的長處短處,專業的網頁開發人員必須了解如何讓網頁在不同瀏覽器上運作正常。這包含處理手機的小視窗,處理離線用戶的行為。 + +這邊有一個值得加到你書籤的實用網頁:[caniuse.com](https://www.caniuse.com)。當你在建構網頁時,你可以查詢 caniuse 技術支援清單,確保你能提供用戶最佳的使用體驗。 + +✅ 你知道你的網頁用戶最常使用什麼瀏覽器嗎?檢查你的分析程式,你可以安裝各種分析程式當作是你開發的一種環節,它們會告訴你那些瀏覽器最常被使用。 + +## 瀏覽器擴充功能 + +為什麼你需要建立瀏覽器擴充功能?它能附加在瀏覽器上,讓你快速地重複執行部分功能。舉例來說,如果你需要在網頁中檢查你所互動的顏色,你或許需要顏色選擇器擴充功能;如果你有記憶帳號密碼的困擾,你可能需要密碼管理擴充功能。 + +瀏覽器擴充功能在開發上也很有趣。它們有效地管理並執行少部分任務課題。 + +✅ 你最喜歡哪一項瀏覽器擴充功能?它們提供了什麼功能? + +### 安裝擴充功能 + +在你建立擴充功能以前,先看看建制與安裝瀏覽器擴充功能的流程。每一種瀏覽器在管理套件上可能有些不同,Edge上的管理過程就與 Chrome 與 Firefox 相似: + +![Edge 瀏覽器開啟 edge://extensions 中的設定選單截圖](../images/install-on-edge.png) + +大體而言,過程為: + +- 指令 `npm run build` 建制你的管理套件 +- 在瀏覽器中的延伸模組區點擊右上方的「更多設定」按鈕 +- 如果這是新的套件,選擇 `load unpacked` 從資料夾上傳新的擴充套件(在我們的例子中, `/dist` ) +- 如果這是已安裝的套件,點擊 `reload` 按鈕 + +✅ 上述教學步驟讓你導入自己建立的擴充功能;若要安裝已公開的套件,你可以前往瀏覽器擴充功能商店,逛逛這些[商店](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home)並安裝你選擇的套件。 + +### 展開行動 + +你打算寫一套擴充功能來顯示你國家的碳足跡,顯示國家的能源使用量與可用能源量。套件內會有 API Key 來存取網頁 CO2 Signal 的 API。 + +**你需要:** + +- [一組 API key](https://www.co2signal.com/):在網頁上輸入你的電子信箱,它會寄一組鑰匙給你 +- 給[Electricity Map](https://www.electricitymap.org/map)使用的[國家區域代碼](http://api.electricitymap.org/v3/zones) (舉個例子,在波士頓使用'US-NEISO') +- [程式碼](../../start),下載 `start` 資料夾,你需要修改裡面的程式碼檔案。 +- [NPM](https://www.npmjs.com),NPM 是一套軟體包管理工具,在本地安裝的軟體包會被列在 `package.json` 檔案中,成為網頁利用的資源。 + +✅ 從[這個優質的學習套件](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa)中,學習更多關於軟體包管理。 + +花點時間看一下程式檔案結構 + +dist + -|manifest.json (defaults set) + -|index.html (前端 HTML) + -|background.js (background JS) + -|main.js (built JS) +src + -|index.js (你的 JS 程式碼) + +✅ 當你取得你的 API Key 與國家區域代碼後,紀錄在筆記中給之後的課程使用。 + +### 建立給擴充功能使用的 HTML + +這套擴充功能有兩個重點。一個是取得 API Key 與國家區域代碼: + +![在瀏覽器擴充功能中,顯示 API key與國家區域代碼的輸入欄截圖](../images/1.png) + +與顯示國家的碳排放量: + +![在瀏覽器擴充功能中,顯示 US-NEISO 地區碳排放量與石化燃料比例截圖](../images/2.png) + +讓我們開始建立輸入欄位的 HTML 與它的 CSS 吧。 + +在資料夾 `/dist` 中,建立輸入表單與結果顯示區域。在檔案 `index.html` 中,規劃表單區域: + +```HTML +
    +
    +

    New? Add your Information

    +
    +
    + + +
    +
    + + +
    + +
    +``` +這個表單儲存你的輸入資訊並儲存到 Local Storage 中。 + +接下來,建立結果輸出區。在 form tag 後面新增一些 divs: + +```HTML +
    +
    loading...
    +
    +
    +
    +

    Region:

    +

    Carbon Usage:

    +

    Fossil Fuel Percentage:

    +
    + +
    +``` +這時,你可以試著建制這個專案。請確保安裝擴充套建的軟體依賴套件,輸入: + +``` +npm install +``` + +這項指令會使用 NPM (Node Package Manager)安裝 webpack 給你的擴充套件建制過程中使用。Webpack 是一個處理程式編譯的工具組合包。你可以在 `/dist/main.js` 看到它的執行後的結果 ── 程式碼已經被打好包了。 + +到目前為止,擴充套件已經被建制,如果你導入此套件到 Edge 中也能完整地呈現出來。 + +恭喜你,你已經達成建立擴充套件的第一步驟。在接下來的課程中,你會新增更多功能,讓它更加的實用。 + +--- + +## 🚀 挑戰 + +逛逛瀏覽器擴充商店,安裝一套擴充功能到你的瀏覽器中。你可以查看它的檔案群。你發現了什麼? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/24) + +## 複習與自學 + +這堂課中你學到了一些瀏覽器的歷史。趁這個機會閱讀更多它的歷史,學習網際網路的發明者是如何構思網路的應用。這邊有一些實用的網頁: + +[瀏覽器的歷史](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) + +[網路的歷史](https://webfoundation.org/about/vision/history-of-the-web/) + +[與 Tim Berners-Lee 的訪談](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want) + +## 作業 + +[重新造型你的套件](assignment.zh-tw.md) + diff --git a/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md b/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md new file mode 100644 index 00000000..2b7dc4d9 --- /dev/null +++ b/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 重新造型你的套件 + +## 簡介 + +本課程的擴充套件已經包含了造型設定,但你不需要非得使用它們。改寫它的 CSS 檔來重新構築擴充插件的造型。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------- | -------------- | ------------ | +| | 新造型能正常地套用在程式中 | 造型規劃不完整 | 套件出現問題 | \ No newline at end of file diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md new file mode 100644 index 00000000..a11d2c09 --- /dev/null +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md @@ -0,0 +1,224 @@ +# 瀏覽器擴充功能專案 Part 1:呼叫 API,使用 Local Storage + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/25) + +### 大綱 + +在這堂課中,藉由傳遞你的擴充功能表單並顯示結果來呼叫 API。此外,你會了解如何儲存資料到瀏覽器的 Local Storage 中給未來使用。 + +✅ 請參考下列程式碼段,加入程式碼到檔案適當的位置 + +### 設定控制擴充功能的元素: + +現在你有已建好的 HTML 表單與結果區 `
    `。接下來,你需要在 `/src/index.js` 做一些處理,一點一點地構築出你的擴充功能。參考[前一堂課程](../../1-about-browsers/translations/README.zh-tw.md)來設置你的專案與了解建制過程。 + +處理 `index.js` 檔案,建立一些 `const` 變數來儲存不同用途的數值: + +```JavaScript +// 表單區域 +const form = document.querySelector('.form-data'); +const region = document.querySelector('.region-name'); +const apiKey = document.querySelector('.api-key'); + +// 結果區域 +const errors = document.querySelector('.errors'); +const loading = document.querySelector('.loading'); +const results = document.querySelector('.result-container'); +const usage = document.querySelector('.carbon-usage'); +const fossilfuel = document.querySelector('.fossil-fuel'); +const myregion = document.querySelector('.my-region'); +const clearBtn = document.querySelector('.clear-btn'); +``` + +這些區域會被 CSS class 給參考,它們在前一堂課中已經被你設定好了。 + +### 新增監聽者 + +接下來,新增提交與重置表單的事件監聽者與按鈕,讓使用者能提交表單或是點擊重置鈕時,事件會發生。新增初始化呼叫處理到應用中,在檔案的最下方新增: + +```JavaScript +form.addEventListener('submit', (e) => handleSubmit(e)); +clearBtn.addEventListener('click', (e) => reset(e)); +init(); +``` + +✅ 注意提交事件與點擊事件的寫法,事件是如何被傳入到 handleSubmit 或是 reset 函式中的。你能在不改變功能的情況下,改寫成較長的格式嗎?你比較喜歡哪一種寫法? + +### 建立 init() 函式與 reset() 函式: + +現在你需要建立函式 init(),處理應用程式的初始化部分: + +```JavaScript +function init() { + //如果任何東西存在 localStorage 中,取出來 + const storedApiKey = localStorage.getItem('apiKey'); + const storedRegion = localStorage.getItem('regionName'); + + //設定 icon 為通用綠色 + //todo + + if (storedApiKey === null || storedRegion === null) { + //如果沒有 keys,顯示表單 + form.style.display = 'block'; + results.style.display = 'none'; + loading.style.display = 'none'; + clearBtn.style.display = 'none'; + errors.textContent = ''; + } else { + //localStorage 有 saved keys/regions,顯示結果 + displayCarbonUsage(storedApiKey, storedRegion); + results.style.display = 'none'; + form.style.display = 'none'; + clearBtn.style.display = 'block'; + } +}; + +function reset(e) { + e.preventDefault(); + //只清除 local storage 國家區域代碼 + localStorage.removeItem('regionName'); + init(); +} + +``` +在函式中,有一些有趣的邏輯。閱讀它們,你看出發生什麼事嗎? + +- 兩個 `const` 被設定為檢查用戶是否有儲存 APIKey 與國家區域代碼在 local storage 中。 +- 若兩者皆為 null,將造型設為 'block' 來顯示表單 +- 隱藏 results、loading 與 clearBtn,設定 error 文字為空字串 +- 若存在 key 與代碼,開始新的流程: + - 呼叫 API 取得碳排放資訊 + - 隱藏結果區域 + - 隱藏表單 + - 顯示重置按鈕 + +在下一步之前,你可以學習一些瀏覽器的重要成員:[LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)。 LocalStorage 是瀏覽器儲存字串的有效方法,以 `key-value` 配對兩兩一組。這種儲存型態可以被 JavaScript 管理並控制瀏覽器的資料。LocalStorage 沒有期限,而另一款網頁儲存 SessionStorage 會在瀏覽器關閉時清除內容。不同的儲存方式有各自的優缺點。 + +> 注意 ── 你的瀏覽器擴充套件有自己的 local storage。主瀏覽器視窗是不同的個體,兩者會做各自的行為。 + +你設定 APIKey 紀錄字串數值。你可以在 Edge 瀏覽器上「檢查」一個網頁 (右鍵瀏覽器來檢查),在 Applications 標籤中觀察儲存區的使用情況。 + +![Local storage 區域](../images/localstorage.png) + +✅ 想想那些情況你不需要儲存資料到 LocalStorage 中。總體而言,將 API Keys 放在 LocalStorage 是個很糟糕的想法!你知道為什麼嗎?在我們的例子中,我們的應用程式是以教學為目的,並不會發布在應用程式商店中,所以我們選擇此中處理方式。 + +你可以發現網頁 API 能處理 LocalStorage,使用 `getItem()`、`setItem()` 或是 `removeItem()`。它們廣泛地支援不同的瀏覽器。 + +在建立函式 `init()` 中的函式 `displayCarbonUsage()` 之前,我們先建立表單提交初始化的功能。 + +### 處理表單提交 + +建立函式 `handleSubmit`,接收事件參數 `(e)`。終止網頁移轉的事件(在本例子中,我們終止瀏覽器刷新的處理)並呼叫新的函式 `setUpUser`,傳送參數 `apiKey.value` 與 `region.value`。藉由這個方式,你能將兩個初始表單的數值正確地移轉到適合的位置。 + +```JavaScript +function handleSubmit(e) { + e.preventDefault(); + setUpUser(apiKey.value, region.value); +} +``` +✅ 刷新你的記憶 ── 上堂課中的 HTML 檔案開頭有兩個輸入區域,它們的 `values` 被存到 `const` 中,並且被定為 `required`,表示瀏覽器禁止使用者輸入空值。 + +### 設定使用者 + +來到函式 `setUpUser`,這裡你能找到 apiKey 與 regionName 被存到 Local Storage 中。新增函式: + +```JavaScript +function setUpUser(apiKey, regionName) { + localStorage.setItem('apiKey', apiKey); + localStorage.setItem('regionName', regionName); + loading.style.display = 'block'; + errors.textContent = ''; + clearBtn.style.display = 'block'; + //建立初始化呼叫 + displayCarbonUsage(apiKey, regionName); +} +``` +這個函式設定當 API 被呼叫時,顯示讀取訊息。到這裡,你即將建立這個擴充功能專案最重要的函式! + +### 顯示碳排放量 + +最後,是時候查詢 API 了! + +在前往下一步前,我們先來討論何謂 API。API,[Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html),是網頁開發者工具箱內最重要的成員。它們提供程式標準的互動模式與溝通介面,舉例來說,如果你建立一個需要存取資料庫的網頁,資料庫方可能就有人建立了 API 供你使用。API 有各式各樣的種類,最普遍使用的為[REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)。 + +✅ 'REST' 全名為 'Representational State Transfer',提供各式各樣 URL 形式來抓取資料。對網路開發者的 API 種類做一點研究,什麼形式的 API 最吸引你? + +這條函式中有一個重要到值得紀錄的事情。第一點為[關鍵字 `async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)。讓你的函式非同步地執行,在行為完成前做等待,譬如資料被回傳。 + +這裡有一個簡短的影片介紹 `async`: + +[![Async 與 Await 處理 promises 物件](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async 與 Await 處理 promises 物件") + +> 點擊上方圖片以觀賞關於 async/await 的影片。 + +建立新的函式來詢問 C02Signal 的 API: + +```JavaScript +import axios from '../node_modules/axios'; + +async function displayCarbonUsage(apiKey, region) { + try { + await axios + .get('https://api.co2signal.com/v1/latest', { + params: { + countryCode: region, + }, + headers: { + 'auth-token': apiKey, + }, + }) + .then((response) => { + let CO2 = Math.floor(response.data.data.carbonIntensity); + + //calculateColor(CO2); + + loading.style.display = 'none'; + form.style.display = 'none'; + myregion.textContent = region; + usage.textContent = + Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)'; + fossilfuel.textContent = + response.data.data.fossilFuelPercentage.toFixed(2) + + '% (percentage of fossil fuels used to generate electricity)'; + results.style.display = 'block'; + }); + } catch (error) { + console.log(error); + loading.style.display = 'none'; + results.style.display = 'none'; + errors.textContent = 'Sorry, we have no data for the region you have requested.'; + } +} +``` + +這是一個挺大的函式,發生了什麼事? + +- 遵循程式實踐過程,你使用關鍵字 `async` 讓函式非同步地作行為。函式內的 `try/catch` 區塊會在 API 回傳資料時回傳 promise 物件。因為我們無法控制 API 會多快地回應訊息(甚至無法回應訊息!),你需要處理這種不確定性的時序關係。 +- 藉由提供 API Key 訪問 co2signal API 以取得你的地區資料。要使用這把鑰匙,你必須在網頁標頭中新增認證參數。 +- 當 API 回應時,你將各種物件填入回傳的數值,並輸出到畫面上中。 +- 如果發生錯誤,或沒有結果產生,輸出錯誤訊息。 + +✅ 非同步程式設計是一種實用的工具。閱讀[更多使用方法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)設定非同步程式的程式碼。 + +恭喜你!當你建制你的專案(`npm run build`)並在瀏覽器上刷新功能,你有個可以運作的應用套件了!現在只差圖示無法正常顯示,我們會在下一堂課中修正它。 + +--- + +## 🚀 挑戰 + +我們在課程中討論了不同種類的 API。選擇一樣網頁 API 並做更深度的研究。舉例來說,看看瀏覽器內支援的 API 如 [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)。依你看,什麼決定了 API 的優劣? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/26) + +## 複習與自學 + +這堂課你學會關於 LocalStorage 與 API,它們對資深網頁開發者提供很大的幫助。你能想想這兩樣東西如何彼此相互合作呢?想想你會如何建構你的網頁,讓 API 得以使用你所儲存的資料。 + +## 作業 + +[認領一項 API](assignment.zh-tw.md) + diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md new file mode 100644 index 00000000..c40fea7c --- /dev/null +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 認領一項 API + +## 大綱 + +API 可以是很好玩的。這裡有[許多公開 API 的清單](https://github.com/public-apis/public-apis)。挑選一項 API,建立一個網頁擴充功能來解決問題。問題可以很小,如找不到足夠的寵物照片,這時你可以嘗試使用[dog CEO API](https://dog.ceo/dog-api/));或是解決更大問題。好好享受吧! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | --------------------------------------------- | ------------------------ | ------------ | +| | 使用上述清單內的 API 建立完整的瀏覽器擴充功能 | 建立部分的瀏覽器擴充功能 | 套件存在問題 | \ No newline at end of file diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md new file mode 100644 index 00000000..93ea7a7a --- /dev/null +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md @@ -0,0 +1,160 @@ +# 瀏覽器擴充功能專案 Part 1:學習背景工作與效能 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/27) + +### 大綱 + +在前兩堂課程中,你學會如何建立表單、顯示 API 回覆的資料在結果區塊中,這是網頁處理網頁資訊的標準行為。你甚至學會了如何非同步性地抓取資料。你的擴充套件就快完成了。 + +它只剩管理背景工作:包括刷新套件的圖示顏色,我們來討論瀏覽器是如何處理這類的工作。也讓我們探討你所建立的網頁,瀏覽器會多有效地處理其中的內容。 + +## 網頁處理效能的基礎 + +> "網頁處理效能攸關兩件事:網頁多快地載入,與程式多快地執行。" -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/) + +關於如何讓你的網頁能快速地運作在各類裝置、各個使用者以及各種情況,是一件難以想像的龐大主題。這裡有一些要點確保你在開發網頁或是擴充功能時,銘記在心。 + +第一件事為確保網頁收集關於網頁效能的資料,在瀏覽器的開發者工具中可以實現它。在 Edge 中,選擇「設定及更多」按鈕(瀏覽器上三個點的圖示),並選擇更多工具 > 開發人員工具並開啟 Performance 分頁。你也可以使用鍵盤快捷鍵,Windows 上的 `Ctrl` + `Shift` + `I` 與 Mac 上的 `Option` + `Command` + `I` 來開啟開發人員工具。 + +Performance 分頁包括了效能分析工具。開啟一個網頁,例如 https://www.microsoft.com,點擊 'Record' 按鈕並重新整理網頁。停止錄製後你就能取得網頁的 'script'、'render' 與 'paint' 的過程與資訊: + +![Edge 性能分析工具](../images/profiler.png) + +✅ 造訪[Microsoft 文件](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa)觀看 Edge 的 Performance 分頁資訊 + +> 提示:要取得真正的網頁開啟時間,記得清除你的瀏覽器快取。 + +選擇一樣網頁在載入時,時間列中出現的事件物件。 + +觀看它的總覽面板並截圖你的網頁效能。 + +![Edge 性能分析工具截圖](../images/snapshot.png) + +檢查 Event Log 面板,是否有網頁事件花超過 15 毫秒: + +![Edge event log](../images/log.png) + +✅ 了解你的性能分析工具!在這個網頁中,開啟開發者工具,檢查是否有任何 bottleneck。什麼是載入最久的物件?哪個又是最快的? + +## 效能分析 + +總體而言,每一位網頁開發者一定要注意一些「有問題的地方」,避免在發布作品時有令人意想不到的驚喜。 + +**資產(Asset)大小**:過去幾年來,網頁「變重」了,也因此變慢了。有些負擔來自於圖片的使用。 + +✅ 查詢[Internet Archive](https://httparchive.org/reports/page-weight),看看過去的網頁負擔等資訊。 + +一個好的習慣是確保你的圖片有做最佳化,呈現合理的檔案大小及解析度影像給你的使用者。 + +**DOM 查找元素(Traversal)**:瀏覽器必須依照你的程式碼建立 Document Object Model,請確保你的 tags 最小化,網頁只使用必須的功能與造型。另外,過量的網頁 CSS 也可以被最佳化,舉例來說,造型樣板只用在單頁上,而非全域上。 + +**JavaScript**:每一位 JavaScript 開發者會觀察 'render-blocking' 腳本,它會在 DOM 查找與瀏覽器呈現前被載入好。請考慮使用 `defer` 在你的程式碼中,我們的盆栽盒專案就有實踐這行。 + +✅ 在[網頁測速網](https://www.webpagetest.org/)上測試一些網頁,學習確認網頁效能的基本檢查。 + +現在你了解瀏覽器如何呈現你所提供的資產,我們來看看我們的擴充功能最後需要補齊的項目: + +### 建立函式計算顏色 + +編輯 `/src/index.js`,新增函式 `calculateColor()` 在一系列為了 DOM 存取的 `const` 變數之後: + +```JavaScript +function calculateColor(value) { + let co2Scale = [0, 150, 600, 750, 800]; + let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02']; + + let closestNum = co2Scale.sort((a, b) => { + return Math.abs(a - value) - Math.abs(b - value); + })[0]; + console.log(value + ' is closest to ' + closestNum); + let num = (element) => element > closestNum; + let scaleIndex = co2Scale.findIndex(num); + + let closestColor = colors[scaleIndex]; + console.log(scaleIndex, closestColor); + + chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } }); +} +``` + +發生了什麼事?你傳遞了 API 回傳的二氧化碳濃度數值,計算出它最適合對應的顏色矩陣索引位置。之後,你將這個顏色數值傳給了 chrome runtime。 + +chrome.runtime 有[一個 API](https://developer.chrome.com/extensions/runtime)處理所有的背景工作,你的擴充套件借助了此功能: + +> "在應用程式中,使用 chrome.runtime API 來接收背景頁面,回傳關於 manifest 的資訊,監聽並回應事件。你也可以利用此 API 轉換 URL 的相對路徑成絕對路徑。" + +✅ 如果你正打算開發此專案給 Edge 瀏覽器上使用,你會訝異你使用的是 chrome API。新的 Edge 瀏覽器執行在 Chromium browser 引擎上,所以你也能使用這些工具。 + +> 注意,如果你想要剖析瀏覽器擴充功能,請在擴充套件上執行開發者工具,它與瀏覽器主視窗為不同的個體。 + +### 設定圖示預設顏色 + +現在,在函式 `init()` 中,利用呼叫 chrome `updateIcon` 設定圖示顏色為通用綠: + +```JavaScript +chrome.runtime.sendMessage({ + action: 'updateIcon', + value: { + color: 'green', + }, +}); +``` +### 呼叫函式、執行呼叫 + +接下來,在 C02Signal API 回傳的 promise 物件下方呼叫函式: + +```JavaScript +//let CO2... +calculateColor(CO2); +``` +最後,在檔案 `/dist/background.js` 中,新增事件監聽者給這些背景行為的呼叫: + +```JavaScript +chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + if (msg.action === 'updateIcon') { + chrome.browserAction.setIcon({ imageData: drawIcon(msg.value) }); + } +}); +//參考 energy lollipop extension,很好的程式! +function drawIcon(value) { + let canvas = document.createElement('canvas'); + let context = canvas.getContext('2d'); + + context.beginPath(); + context.fillStyle = value.color; + context.arc(100, 100, 50, 0, 2 * Math.PI); + context.fill(); + + return context.getImageData(50, 50, 100, 100); +} +``` +在此程式中,你建立了事件監聽者給任何前到背景工作管理者的訊息。若 'updateIcon' 被呼叫,則接下來的程式會被執行,利用 Canvas API 繪製出對應顏色的圖示。 + +✅ 你會學習更多關於 Canvas API 在往後的[太空遊戲課程](../../6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md)。 + +現在,重新建制你的擴充功能(`npm run build`),刷新並運行你的套件,觀察圖示的顏色變化。現在是時候去跑腿或是洗碗嗎?現在你知道了! + +恭喜你,你已經建立了一款實用的瀏覽器擴充功能,並學到更多瀏覽器的運作方式與監測它的效能分析。 + +--- + +## 🚀 挑戰 + +調查一些悠久的開源網站,並根據它們的 GitHub 歷史,你能分辨它們過去幾年以來效能上的調整嗎?什麼它們是共同的痛點? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/28) + +## 複習與自學 + +請考慮註冊[performance newsletter](https://perf.email/) + +調查瀏覽器測量網頁效能的方法,查看開發者工具內的 Performance 分頁。你能找到什麼巨大的差別嗎? + +## 作業 + +[分析網頁效能](assignment.zh-tw.md) + diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md new file mode 100644 index 00000000..8f733b7e --- /dev/null +++ b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md @@ -0,0 +1,9 @@ +# 分析網頁效能 + +請提供一份詳細的報告,點出一個網頁效能上的問題點。分析網頁緩慢的原因並提供改善它的方案。不要只依賴瀏覽器工具,做一點研究尋找更多幫助你的工具。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------------------------- | -------------- | ------------ | +| | 詳細的報告包括非瀏覽器的第三方工具 | 呈現出標準報告 | 報告內容有限 | \ No newline at end of file diff --git a/5-browser-extension/translations/README.zh-tw.md b/5-browser-extension/translations/README.zh-tw.md new file mode 100644 index 00000000..79fb9e0e --- /dev/null +++ b/5-browser-extension/translations/README.zh-tw.md @@ -0,0 +1,28 @@ +# 建立瀏覽器擴充功能 + +建立瀏覽器擴充功能是個好玩且有趣的方式來思考應用程式的執行效能,包含各式各樣類型的網頁資產。這堂學習模組介紹了瀏覽器運作方式、如何架設擴充功能、建立表單、呼叫 API、使用 Local Storage 和測量網頁效能的方法並增進它。 + +你會建立一個支援在 Edge、Chrome 與 Firefox 的瀏覽器擴充功能。這個擴充功能就像小型的網頁,專門滿足特定課題:利用[C02 Signal API](https://www.co2signal.com)檢查地區的電力使用與碳排濃度,回傳地區的碳足跡。 + +這款特設擴充功能允許使用者在輸入完 API Key 與國家地區代碼到表單後,取得當地電力使用量與其他資訊,決定使用者後續的行為。舉例來說,在地區高電力用量時,你可能會延後烘衣機的使用(增加碳排)。 + +### 主題 + +1. [關於瀏覽器](../1-about-browsers/translations/README.zh-tw.md) +2. [表單與 Local Storage](../2-forms-browsers-local-storage/translations/README.zh-tw.md) +3. [背景工作與效能](../3-background-tasks-and-performance/translations/README.zh-tw.md) + +### 成就 + +![綠能瀏覽器擴充功能](extension-screenshot.png) + +## 參與人員 + +網頁碳排放追蹤的發想出自於 Asim Hussain,微軟綠能雲端倡導小組的領導人與[Green Principles](https://principles.green/)的作者。這源自於一個[網頁專案](https://github.com/jlooper/green)。 + +擴充功能的結構受[Adebola Adeniran 的 COVID 擴充功能](https://github.com/onedebos/covtension)啟發。 + +「點」圖示系統的概念參考[Energy Lollipop](https://energylollipop.com/)的加州排放擴充功能。 + +這些課程由 [Jen Looper](https://www.twitter.com/jenlooper) 用滿滿的 ♥️ 來編寫。 + From 93c02d6d70693c57a7f5a47e96336c0e9a141a69 Mon Sep 17 00:00:00 2001 From: CRTao Date: Mon, 8 Mar 2021 16:03:15 +0800 Subject: [PATCH 08/13] translate lesson 6 to zh-tw --- quiz-app/src/assets/translations/zh-tw.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/quiz-app/src/assets/translations/zh-tw.json b/quiz-app/src/assets/translations/zh-tw.json index 38cab74f..98cc0464 100644 --- a/quiz-app/src/assets/translations/zh-tw.json +++ b/quiz-app/src/assets/translations/zh-tw.json @@ -1580,7 +1580,7 @@ }, { "id": 31, - "title": "課程十六 - 太空遊戲 - 繪製英雄怪物於畫布:課前測驗", + "title": "課程十六 - 太空遊戲 - 在畫布繪製英雄與怪物:課前測驗", "quiz": [ { "questionText": "你可以利用Canvas元素在螢幕上繪製圖案。", @@ -1625,7 +1625,7 @@ }, { "id": 32, - "title": "課程十六 - 太空遊戲 - 繪製英雄怪物於畫布:課後測驗", + "title": "課程十六 - 太空遊戲 - 在畫布繪製英雄與怪物:課後測驗", "quiz": [ { "questionText": "繪圖處理能直接應用在Canvas上。", @@ -1674,7 +1674,7 @@ }, { "id": 33, - "title": "課程十七 - 太空遊戲 - 加入律動:課前測驗", + "title": "課程十七 - 太空遊戲 - 加入動作:課前測驗", "quiz": [ { "questionText": "任何物件可以接收鍵盤事件。", @@ -1723,7 +1723,7 @@ }, { "id": 34, - "title": "課程十七 - 太空遊戲 - 加入律動:課後測驗", + "title": "課程十七 - 太空遊戲 - 加入動作:課後測驗", "quiz": [ { "questionText": "更新螢幕一定要全部重新繪製。", @@ -1902,7 +1902,7 @@ ] }, { - "questionText": "為什麼遊戲需要有「生命數」的概念?", + "questionText": "為什麼遊戲需要有「性命數」的概念?", "answerOptions": [ { "answerText": "為了表現玩家還能承受多少攻擊。", @@ -1935,10 +1935,10 @@ }, { "id": 38, - "title": "課程十九 - 太空遊戲 - 分數與生命數:課後測驗", + "title": "課程十九 - 太空遊戲 - 分數與性命數:課後測驗", "quiz": [ { - "questionText": "如何有趣地表現出玩家剩餘的生命數?", + "questionText": "如何有趣地表現出玩家剩餘的性命數?", "answerOptions": [ { "answerText": "剩餘艦艇的數字。", From cbdc177742bda031d3d54c94ed3a92f85f264d68 Mon Sep 17 00:00:00 2001 From: CRTao Date: Fri, 12 Mar 2021 10:57:38 +0800 Subject: [PATCH 09/13] translate lesson 7 to zh-tw --- .../translations/README.zh-tw.md | 307 ++++++++++++++++ .../translations/assignment.zh-tw.md | 14 + .../2-forms/translations/README.zh-tw.md | 297 ++++++++++++++++ .../2-forms/translations/assignment.zh-tw.md | 13 + .../3-data/translations/README.zh-tw.md | 336 ++++++++++++++++++ .../3-data/translations/assignment.zh-tw.md | 15 + .../translations/README.zh-tw.md | 284 +++++++++++++++ .../translations/assignment.zh-tw.md | 25 ++ .../api/translations/README.zh-tw.md | 33 ++ quiz-app/src/assets/translations/zh-tw.json | 4 +- 10 files changed, 1326 insertions(+), 2 deletions(-) create mode 100644 7-bank-project/1-template-route/translations/README.zh-tw.md create mode 100644 7-bank-project/1-template-route/translations/assignment.zh-tw.md create mode 100644 7-bank-project/2-forms/translations/README.zh-tw.md create mode 100644 7-bank-project/2-forms/translations/assignment.zh-tw.md create mode 100644 7-bank-project/3-data/translations/README.zh-tw.md create mode 100644 7-bank-project/3-data/translations/assignment.zh-tw.md create mode 100644 7-bank-project/4-state-management/translations/README.zh-tw.md create mode 100644 7-bank-project/4-state-management/translations/assignment.zh-tw.md create mode 100644 7-bank-project/api/translations/README.zh-tw.md diff --git a/7-bank-project/1-template-route/translations/README.zh-tw.md b/7-bank-project/1-template-route/translations/README.zh-tw.md new file mode 100644 index 00000000..57a70b05 --- /dev/null +++ b/7-bank-project/1-template-route/translations/README.zh-tw.md @@ -0,0 +1,307 @@ +# 建立銀行網頁應用程式 Part 1:HTML 模板與網頁路由 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/41) + +### 大綱 + +自從 JavaScript 出現在瀏覽器後,網頁開始變得更複雜、更多互動。網頁技術已經普遍地用於建立功能齊全的應用程式,執行在瀏覽器上,我們稱之為[網頁應用程式](https://zh.wikipedia.org/zh-tw/%E7%BD%91%E7%BB%9C%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F)。基於網頁應用程式的高互動性,使用者不會想在互動後做所有頁面載入所需的等待。這也是為什麼 JavaScript 使用 DOM 來更新 HTML,提供使用者更流暢的網頁體驗。 + +在這堂課程中,我們會譜出銀行網頁應用程式的基礎,使用 HTML 模板建立不同的畫面,各自顯示並更新內容,而不必每次都需要載入整個 HTML 頁面。 + +### 開始之前 + +你需要一個網頁伺服器來測試我們要建的專案。如果你還沒有,你可以安裝 [Node.js](https://nodejs.org) 並在你的專案資料夾中使用指令 `npx lite-server`。這會建立一個本地端的網頁伺服器,在瀏覽器上開啟你的網頁程式。 + +### 準備 + +在你的電腦上,建立資料夾 `bank`,並在裡面建立檔案 `index.html`。我們以這個 HTML [樣板](https://en.wikipedia.org/wiki/Boilerplate_code)來開始: + +```html + + + + + + Bank App + + + + + +``` + +--- + +## HTML 模板(templates) + +如果你想在同一個網頁上建立不同的畫面,其中一種方法是各自建立一個 HTML 檔給每一個你想呈現的子畫面。然而,這個方式有許多不便之處: + +- 你需要在切換頁面時,重新載入整個網頁。這會很花時間。 +- 在不同子頁面上共享數據會是一大難題。 + +另一個解決方案是只有一個 HTML 檔案,並使用 `