JavaScript 與 jQuery

第 1 章    程式設計 ABC

(1) 何謂命令稿

∗ 命令稿 (Script):

▸ 一連串電腦可以遵循的指令,以達成目標

▸ 就像食譜 (Recipe),只要遵照食譜所記載的步驟一步一步進行,就能完成餐點

∗ 撰寫命令稿:

▸ 從大處著眼,將所要完成的目標分解成為小步驟

▸ 定義目標:首先需要定義要達成的目標:例如電腦要完成的拼圖遊戲

▸ 設計命令稿

✶ 將目標分解成為一系列電腦所要執行的小工作,可以利用流程圖 (Flowchart)
✶ 接下來將每個小工作的內容寫下

▸ 將每個步驟轉寫為程式 (Code)

∗ 範例 1:飯店房間清理 (較像人類指令)

▸ 流程圖:飯店清潔員的工作

Hotel cleaning
∗ 整理房間之步驟:
1. 移除使用過的寢具
2. 擦拭所有表面
3. 地板吸塵
4. 換上新的寢具
5. 移除使用過的毛巾與皂品
6. 清潔廁所、浴室、洗手枱之表面
7. 換上新的毛巾與皂品
8. 清潔浴室地板

▸ 流程圖是一個高階視圖 (High-level view),呈現完成目標的過程

▸ 各個子工作都可以分解為一連串的步驟,以程式而言,這些步驟就可以轉換為一行一行的程式指令

∗ 程式設計師必須學習「如何像電腦一般思考」,包括:

▸ 程式語言的詞彙 (Vocabulary)

▸ 程式語言的語法 (Syntax)

▸ 利用程式方法來解決問題 (Programmatic approach of problem-solving)

✶ 電腦以程式的方法來解決問題
✶ 程式方法:一系列電腦所執行指令,這樣的方法和人類所使用的指令很不相同

∗ 範例 2:計算製作名牌的費用 (較像電腦指令)

▸ 在系統頁面中有輸入欄位,讓顧客輸入名字,然後計算名牌製作費用

▸ 首先定義目標:顧客可以製作名牌,每個字 50 元,當顧客輸入名字後,顯示費用

▸ 其次將完成目標的過程定義為一系列的工作:

✶ 顧客首先填入欲製作名牌的名字
✶ 當按下「顯示費用」按鈕後,命令稿開始執行:
# 收集顧客在表單所輸入的名字資料
# 檢查顧客是否有輸入資料
# 如果沒有輸入資料,顯示「請輸入資料」訊息
# 如果有輸入資料,計算製作費用:字元數量乘以每個字元的費用
# 顯示結果費用
name plate1     name plate2     name plate3

(2) 電腦如何與世界互動

∗ 電腦利用資料來產生世界的模型 (Model)

例如一個飯店及週邊 2 部汽車的模型

▸ 在模型中,每個實體可以利用物件 (Object) 來表示,因此此模型中有兩個物件型態:飯店及汽車

▸ 程式設計師也會說:此模型中有一個飯店實例 (Instance) 與兩個汽車實例

▸ 每個物件可以有自己的:特性 (Property)、事件 (Event)、及方法 (Method)

∗ 物件與特性

▸ 模型中的兩部汽車其實有一些共同的特性:廠牌、顏色、引擎容量等

▸ 每個特性有名稱 (Name) 及值 (Value),這樣的「名稱/值」的配對可以辨識某個實例

▸ 飯店物件:利用下列特性來說明此飯店

OBJECT TYPE: HOTEL
PROPERTIES
name Dorchester
rating 4
rooms 42
bookings 21
gym false
pool true

▸ 汽車物件:利用下列特性來說明 2 部汽車

OBJECT TYPE: CAR
PROPERTIES
make Maserati
color silver
currentSpeed 40 kmph
fuel diesel

OBJECT TYPE: CAR
PROPERTIES
make Ferrari
color black
currentSpeed 60 kmph
fuel gasoline

∗ 事件 (Event)

▸ 在真實世界中,人們與物件互動,這些互動會改變物件特性的值

▸ 何謂事件?

✶ 人們與不同物件互動有不同的模式,例如:與汽車互動可以包含加油與煞車踏板,當踩下加油踏板汽車就加速,當踩下煞車踏板汽車就減速
✶ 以電腦的立場而言,所謂「事件」就是某件事發生了,例如踩下加油踏板事件發生了,或者踩下煞車踏板事件發生了

▸ 事件的運作機制

✶ 程式設計師會針對不同的事件來設計不同的回應,當事件發生就會驅動回應,例如踩下加油踏板事件發生的回應就是「汽車加速」
✶ 程式設計師在程式中會指明需要回應哪些事件,以及哪個事件會驅動程式哪些部份的執行

▸ 飯店物件的事件:訂房與取消訂房

OBJECT TYPE: HOTEL
EVENT happens when:
book reservation is made
cancel reservation is canceled

▸ 汽車物件的方法:加速與煞車

OBJECT TYPE: CAR
EVENT happens when:
brake driver slows down
accelerate driver speeds up

∗ 方法 (Method)

▸ 方法表示人們對於物件的操作,可以取出或修改物件特性的值

▸ 何謂方法?

✶ 方法描述在真實世界中,人們如何和物件互動
✶ 方法就像問題或指令一樣:
# 問題:告訴你物件的特性
# 指令:改變物件特性的值

▸ 方法的運作機制

✶ 當你使用一個方法時:
# 問題:只要知道如何詢問,並且如何解讀回覆
# 指令:只要知道如何設定或修改某個特性的值

▸ 飯店物件的方法:訂房、取消訂房、是否有空房

OBJECT TYPE: HOTEL
METHOD what it does:
makeBooking() increases value of booking property
cancelBooking() decreases value of booking property
checkAvailability() subtracts value of booking property from value of rooms property and returns number of rooms available

▸ 汽車物件的事件:加速與煞車

OBJECT TYPE: CAR
METHOD what it does:
changeSpeed() increases or decreases value of currentSpeed property

∗ 全部整合在一起

▸ 電腦使用資料來產生真實世界中物件的模型

▸ 一個物件的事件、方法、與特性彼此都相關:

✶ 事件驅動方法,方法可以取出或修改特性

▸ 飯店物件的操作:

(1) 當訂房時,觸發 book 事件
(2) book 事件驅動 makeBooking() 方法, 而增加 bookings 特性的值
(3) bookings 特性的值可反映目前有多少空房
OBJECT TYPE: HOTEL
EVENT happens when: method called: PROPERTIES
book   (1) reservation is made makeBooking() name Dorchester
cancel reservation is canceled cancelBooking() rating 4
METHOD what it does: rooms 42
makeBooking()   (2) increases value of booking property bookings 22   (3)
cancelBooking() decreases value of booking property gym false
checkAvailability() subtracts value of booking property from value of rooms property and returns number of rooms available pool true

▸ 汽車物件的操作:

(1) 當駕駛加速時,觸發 accelerate 事件
(2) accelerate 事件驅動 changeSpeed() 方法, 而增加 currentSpeed 特性的值
(3) currentSpeed 特性的值可反映目前汽車的速度
OBJECT TYPE: CAR
EVENT happens when: method called: PROPERTIES
brake driver slows down changeSpeed() make Chrysler
accelerate   (1) driver speeds up changeSpeed() currentSpeed 70 kmph   (3)
METHOD what it does: color silver
changeSpeed()   (2) increases or decreases value of currentSpeed property fuel diesel

(3) 網頁如何與世界互動

∗ 網頁是由物件建構而成

▸ 視窗 (Window) 物件:瀏覽器的視窗或頁籤就是一個 window 物件

✶ Location 特性:Window 物件的 location 特性儲存目前網頁的 URL

▸ 文件 (Document) 物件:載入瀏覽器視窗或頁籤的網頁利用 document 物件來模型化

✶ Title 特性:Document 物件的 title 特性儲存網頁的標題, 也就是 HTML 元素 <title> 標籤的內容
✶ LastModified 特性:Document 物件的 lastModified 特性儲存網頁最後修改時間

∗ Document 物件表示一個 HTML 網頁

▸ 利用 document 物件,我們可以存取或修改使用者所看到網頁的內容,也可以讓使用者和網頁互動

document 物件同樣地也擁有:

✶ 特性:描述目前網頁的特質
✶ 方法:可取出網頁元素的內容,增加、刪除、或修改網頁內容
✶ 事件:我們可以回應使用者所觸發的事件,例如滑鼠點擊某個元素
OBJECT TYPE: DOCUMENT
PROPERTIES
URL http://www.javascriptbook.com/
lastModified 2014-9-4 15:33:37
title Learn JavaScript & jQuery – A book that teaches you in a nicer way
EVENT happens when:
load page and assets have finished loading
click user clicks the mouse over the page
keypress user presses down on a key
METHOD what it does:
write() adds new content to the document
getElementById() accesses an element when you state its id attribute

▸ 因為所有瀏覽器都以相同的方式實作 document 物件,研發瀏覽器的專家們已經:

✶ 建立許多網頁的特性,我們可以直接取用
✶ 撰寫了許多方法,我們可以直接呼叫

▸ 當網頁載入瀏覽器後,瀏覽器不僅建立 document 物件,同時也建立該網頁所有元素的物件, 這些物件總稱為文件物件模型 (Document Object Model, DOM)

∗ 瀏覽器如何看待網頁

要了解如何利用 JavaScript 改變 HTML 網頁的內容,我們要先知道瀏覽器如何解讀 HTML 碼 (HTML code), 以及如何為網頁元素加上樣式 (Style),程序如下:

1.  瀏覽器接收到一份 HTML 碼

✶ 一個網站的每個網頁都可看成一個 document,當連到某個網頁時,瀏覽器接收到一份 HTML document,例如:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>My title</title>
<link rel="stylesheet" href="css/myCss.css">
</head>
<body>
<h1>My company</h1>
<p>Phone: <em>1234-5678</em></p>
</body>
</html>

2.  瀏覽器為網頁建立一份模型 (Model) 並且儲存在記憶體中,例如:

DOM image

3.  瀏覽器利用顯示引擎 (Rendering engine) 來呈現網頁

✶ 如果沒有 CSS 樣式,就使用預設樣式
✶ 如果有 CSS 樣式,顯示引擎處理 CSS 樣式規則,然後應用在相對的 HTML 元素

(4) 在網頁中撰寫命令稿

∗ HTML、CSS、與 JavaScript 的結合可視為三層結構:

▸ 內容層 (Content layer):HTML 碼,儲存網頁的內容、結構、與意義

▸ 展示層 (Presentation layer):CSS 碼,說明網頁的內容呈現的樣式

▸ 行為層 (Behavior layer):JavaScript 程式碼,改變網頁的行為、加入互動性

→ 此三層的資料最好放在不同的檔案 (.html, .css, .js) 便於個別維護,開發者常稱為關注點分離 (Separation of concerns)

Separation of concerns

∗ 撰寫 JavaScript 程式

▸ JavaScript 程式以純文字方式撰寫,因此只要有純文字編輯器即可,常見的文字編輯器有: Sublime Text 3, Brackets, Atom, Bluefish, notepad++, Gedit

▸ 在 Ubuntu 系統上安裝 Brackets:兩種方式

1. 利用 Ubuntu PPA (此方式較好,版本會自動更新)
$ sudo add-apt-repository ppa:webupd8team/brackets
$ sudo apt update
$ sudo apt install brackets
(註:指令行裡的 $ 是系統提示符號,不需輸入)
2. 下載安裝檔 (http://brackets.io/),再進行安裝

▸ 在 Windows 或 Mac 系統上安裝 Brackets:

✶ 下載安裝檔 (http://brackets.io/),再進行安裝

▸ 設定Brackets

✶ 設定中文繁體介面:Debug → Switch Language → 繁體中文 → Reload Brackets
✶ 選擇字型:檢視 → 佈景主題 → 字體大小:14px,字體 (選等寬字體):
# Ubuntu:DejaVu Sans Mono Book
# MS Windows:Consolas
✶ 設定按下 Tab 鍵的結果是輸入 2 個空白,而不是定位鍵
# 點選右下方設定:最後呈現「空白字元:2」
# 註:在空白處移動游標時,看起來還是一次移動 2 格 (感覺上還是輸入了定位鍵), 這是 Brackets 的智慧功能,一次跳至所設定空白字元的數量
✶ 因為 Brackets 的智慧縮排一點也不智慧,且 JavaScrit 語法錯誤偵測 (JsLint) 也不好用,因此將兩個都停用
# 在 Brackets 裡,點選 「除錯」 --> 「開啟喜好設定檔」 (或:Debug --> Open Preferences File) 即可編輯 brackets.json 設定檔,在最後加入 2 行
{
    "brackets-eslint.gutterMarks": true,
    .
    .
    ...,
    "smartIndent": false,
    "linting.enabled": false
}
# 註:原先最後一行後面要加逗點,加入後的最後一行沒有逗點

∗ 規劃專案目錄架構

▸ 專案目錄架構如下:

javaScript/
   ch1/
      css/
      img/
      js/
   ch2/
      css/
      img/
      js/
   ch3/
   ...
✶ 最上層目錄為 javaScript (以 Ubuntu 作業系統為例, 可以設在 /home/<username>/目錄之下,其中 <username> 是登入的使用者名稱)
# 各章的目錄名稱為 ch1, ch2, ch3, ...
# 每一章目錄均包含 3 個子目錄:css/, img/, 與 js/,分別置放 CSS 樣式,影像、與 JavaScript 等檔案

▸ 註:本教材的目錄架構主要以 Ubuntu 作業系統的表示法為主, 在 Windows 系統中的目錄則以反斜線 (\) 表示

∗ 建立新 HTML 檔案

▸ 建立第 1 章之目錄架構,啟動 Brackets 並移至目的資料夾

檔案 → 開啟資料夾 → 選擇 <...>/javaScript/ 目錄 → 開啟
✶ 設定目的資料夾之後,基於安全機制,Brackets 內建的伺服器僅能存取該資料夾以下的資料,該資料夾以上的資料都無法存取

▸ 建立新檔案 add-content.html

檔案 → 新增 → ctrl-s → 選擇 <...>/javaScript/ch1/ 目錄, 檔名:add-content.html → 儲存,輸入以下內容:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>穩固建築公司</title>
<link rel="stylesheet" href="css/ch1.css">
</head>
<body>
<h1>穩固建築公司</h1>
<script src="js/add-content.js"></script>
<p>下訂單及查詢,請電 <em>(04)2332-3000</em></p>  
</body>
</html>
✶ 在 HTML 檔案中
# 將 JavaScript 程式寫在 <script></script> 標籤中即可執行
# 亦可利用 <script src=...></script> 標籤來連結 JavaScript 檔案, src 為 source (來源) 的縮寫

∗ 建立新 JavaScript 檔案

▸ 建立新檔案 add-content.js

檔案 → 新增 → ctrl-s → 選擇 ch1/js/ 目錄, 檔名:add-content.js → 儲存,輸入以下內容:
var today = new Date();
var hourNow = today.getHours();
var greeting;

alert('第一個JavaScript程式');

if (hourNow > 18) {
  greeting = '晚安';
}
else if (hourNow > 12) {
  greeting = '午安';
}
else if (hourNow > 0) {
  greeting = '早安';
}
else {
  greeting = '歡迎';
}

document.write('<h3>' + greeting + '</h3>');
✶ 先不討論程式內容,僅觀看程式如何執行

∗ 下載相關檔案並瀏覽結果

▸ 下載 assets1.zip,解壓縮後將 ch1.cssbackground.png 檔案分別置於 ch1/css/ch1/img/ 目錄裡

▸ 在瀏覽器開啟 add-content.html

✶ 首先彈出訊息視窗:「第一個 JavaScript 程式」
✶ 按下確定後,可以看到依目前時間所出現適當的致意文字 (「...安」)
✶ 若以滑鼠右鍵點擊網頁並選擇檢視原始檔,可看到 HTML 內容,其中並無致意的元素
✶ 但按下 F12 檢視網頁內容,可以看到 <h3>...安</h3> 元素, 這是由 JavaScript 程式 動態 插入的資料

∗ 也可以將 JavaScript 程式寫入 HTML 檔案

add-content.html

...
<h1>穩固建築公司</h1>
<script>document.write('<h3>歡迎</h3>')</script>
<p>下訂單及查詢,請電<em>(04)2332-3000</em></p>  
<script src="js/add-content.js"></script>
...
→ 可在網頁中看到「歡迎」字眼

▸ 建議:除非必要,否則最好不要將 HTML 與 JavaScript 程式混在一起

∗ 使用 JavaScript 的物件與方法

document.write('歡迎');

document 物件:代表整個網頁

▸ 句點 (.):稱為成員運算子 (Member operator),用來呼叫物件的某個成員 (即方法)

'歡迎':呼叫方法所給的參數 (Parameter)

∗ JavaScript 的執行與其所在位置有關

▸ 當瀏覽器載入網頁過程中,碰到 <script> 元素, 瀏覽器會暫停頁面載入,然後載入 JavaScript 程式並執行,因此執行結果就發生在載入 JavaScript 之處

▸ 上例中,JavaScript 置於 <p>下訂單... </p> 之前,因此其執行結果會在其前顯示

▸ 如無位置需求,JavaScript 的連結應放在網頁最後 (亦即</body> 之前), 以確保網頁所有元素都載入完畢,才載入 JavaScript 程式

▸ 將 JavaScript 撰寫在獨立檔案比寫在網頁中較好

✶ 避免與 HTML 程式碼混雜
✶ JavaScript 程式只會載入一次,但網頁會隨著使用者點選而多次載入,將程式放在網頁中造成不必要的多次下載

上一章       下一章