JavaScript CSS3

Javascript 動態網頁程式設計 - 上課教材

動畫互動網頁程式設計 > 課程內容 > 第 04 章 - 使用 if 與 switch 進行邏輯判斷

第 04 章 - 使用 if 與 switch 進行邏輯判斷

上次更新日期 2020/09/22

所謂的『邏輯判斷』就是透過前一章節討論的布林值所回傳的真與假 (true and false) 作為判斷依據,如果狀態為真,那就進行事件一, 如果狀態為假,那就進行事件二這樣。透過邏輯判斷,我們就可以讓系統做個比較有趣的變化了。

學習目標:

  1. 了解邏輯判斷式
  2. 了解流程圖的圖示意義
  3. 實際操作 if 程式
  4. 實際操作 switch 程式
  5. 數值函數的亂數與整數應用

4.1: 邏輯判斷式

其實前一章的布林值變數型別裡面我們就曾經講到邏輯判斷了,就是透過底下的方式來取得邏輯判斷的回傳值為 true 或 false

var logic1 = ( bmi > 24 );

此時 logic1 只會取得 true 或 false 這種布林值型別的值而已。所以說,邏輯運算就是答案為『 true 』或『 false 』的運算啊! 一般的邏輯運算式,大致是這樣的:

變數或常數  關係運算  變數或常數
   A          >        15
   B          <=       12

變數或常數  等於運算  變數或常數
   S          ==       Q
   Y          !=       Q

你可以看到關係運算主要就是大於等於小於之類的符號,至於驚嘆號 (!) 有『不是、反向』選擇的意思,這些運算都只會回傳 true 或 false 喔! 因為是邏輯運算啊!

  • 複合邏輯計算

如果要同時滿足兩個以上的條件才邏輯判斷為真,那就是我們以前學數學所謂的 and 囉!如果是兩個條件的任何一個成立時,就會回傳值為真, 那就是 or 囉!例如前一章提到的 BMI 計算結果:

var bmi;
( bmi > 18.5 ) && ( bmi < 24 )    // BMI 需要同時大於 18.5 與小於 24 才是真
( bmi < 18.5 ) || ( bmi > 24 )    // BMI 小於 18.5 或者是大於 24 都可接受為真

所以,這個時候 && 以及 || 的協助就非常重要了!另外,邏輯判斷完畢之後,當然重點就是得要設計『當回傳 true 時,要進行什麼事? 而當回傳 false 時,則是進行另外的什麼事』這樣。那如何設計這方面的程式呢?這時最好先要有流程圖的概念:

  • 流程圖圖示

一般來說,流程圖慣用的圖示樣式與代表的意義有點像這樣:

流程圖圖示的示意

舉例來說,要判斷你的 BMI 指數是否合於正常範圍,那可以這樣設計:

流程圖圖示的示意

也就是透過邏輯判斷出 BMI 有沒有超出 18.5~24 之間的範圍,在此範圍內 (true) 就以身體素質正常進行程式運作, 若不在此範圍內 (false),就使用其他程序進行,讓填寫者確認自己的身體狀況可能可以怎麼改善比較妥當之類的。 這時就可以搭配程式來將各個流程圖內的資料完整化了。

4.2: 使用 if 進行條件判斷

使用 if 進行邏輯判斷,主要的語法是這樣的:

if  (邏輯判斷) {
	// 當回答為 true 時的工作
	...
}

但是,總有邏輯判斷總有真假吧?所以,如果真假兩件事分別依據邏輯判斷回應值而進行的話,就會變這樣:

if  (邏輯判斷) {
	// 當回答為 true 時的工作
	程式碼...
} else {
	// 當回答為 false 時的工作
	程式碼...
}

那如果有多個選項呢?基本上可以透過多重邏輯判斷的,例如:

if  (邏輯判斷-1) {
	// 當邏輯判斷-1 回答為 true 時的工作
	程式碼...
} else if (邏輯判斷-2) {
	// 當邏輯判斷-2 回答為 true 時的工作
	程式碼...
} else {
	// 當邏輯判斷-1 與 邏輯判斷-2 回答都是 false 時的工作
	程式碼...
}
例題 4-2-1:回答 BMI 數值的意義
  1. 建立 unit04-2-1.php 檔案,並且在index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 使用 這個檔案 的內容貼上 unit04-2-1.php 當中。
  3. 如同檔案內的設定,建立 ansbmi 函數,並且同時判斷兩個同時成立的邏輯運算 (&&),亦即 bmi >=18.5 與 bmi <=24 的情況:
    • 若回傳為 true 時,顯示訊息 (可以設定一個變數處理) 為:『體重狀態很優良啊!』
    • 若回傳為 false 時,顯示訊息為:『體重的狀態不是很好喔!』
第一個 if 判斷

若只有真與假,那使用 if () {} else {} 即可,但如果一個判斷裡面有多種狀態呢?例如上面 BMI 的案例中,如果有體重過輕 ( BMI < 18.5)、 體重優良 (18.5 ≤ BMI < 24)、體重稍重 (24 ≤ BMI < 28) 與肥胖 (28 ≤ BMI)等,那處理的方案就得要使用多重狀態, 亦即增上多個 else if 即可喔!

例題 4-2-2:回答 BMI 數值的意義
  1. 將 unit04-2-1.php 另存新檔成為 unit04-2-2.php,並且在index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 透過 if ... else if 的功能,將回傳的訊息增加為 4 種狀態,亦即過輕、正常、稍重與肥胖。
使用 else if 的功能
  • 使用 if 設計 UI 界面

如下圖,假設我們需要計算面積,而且需要依據不同的形狀來提供使用者輸入的資訊,這該如何設計?最簡單,就是將所有需要出現的, 通通給它放上來即可。問題是,這樣對於使用者的提示來說,好像有點混亂。

討論 UI 界面

所以,我們是否能夠依據使用者點選不同的面積時,才出現所需要的 input 資訊?然後提供計算的結果呢? 似乎可以透過 if 的方式,當使用者點選相關的形狀後,再來使用 innerHTML 處理吧!設計看看:

例題 4-2-3:使用 if 設計簡單的 UI
  1. 建立 unit04-2-3.php 檔案,並且在index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 使用 這個檔案 的內容貼上 unit04-2-3.php 當中,並且先查看應用一下該網頁。
  3. 先增加 label 的功能,讓使用者點選形狀的字體時,也能夠勾選單選項目。
  4. 將兩個數值的 input 取消,然後增加兩個 div,其 id 分別為 inp1 與 inp2 好了, 這兩個 div 是預計作為等等是否需要有兩個輸入框的預留環境
  5. 開始設計 myselect() 函數:
    • 由於我們的 form 使用了 myform 為 id,因此先設定一個變數名稱為 myform ,並且用以取得 id 為 myform 的表單元素。
    • 設計一個名為 myselect 的變數,內容為 myform.sel.value 這個單選資料 (請注意 form 大部分只對 input 有父、子關係!
    • 分別設計兩變數,分別是 inp1, inp2,分別取得 inp1 與 inp2 這兩個 id 的元素資訊
    • 判斷 myselect 是否為 1, 2, 3 等不同的數據,根據不同的數據來填寫 inp1.innerHTML 與 inp2.innerHTML, 就可以處理不同形狀的輸入框了。
    • 設計完成之後,當你點選不同的形狀時,畫面應該會出現相對應的輸入框才對,如下所示: 討論 UI 界面 討論 UI 界面
  6. 開始設計 mycal() 函數:
    • 一樣設計 myform 變數,取得 myform 頂層表單元素
    • 一樣設計 myselect 變數,內容為 myform.sel.value 即可。
    • 當 myselect == "1" 時,將 myform.num1.value 轉為數值後,使用 πr2 計算面積
    • 當 myselect == "2" 時,將 myform.num{1|2}.value 轉為數值後,使用 (1/2底*高) 計算面積
    • 當 myselect == "3" 時,將 myform.num{1|2}.value 轉為數值後,使用 (長*寬) 計算面積
    • 將計算完畢的面積丟入 myform.ans.value 當中。
搭配一點點簡單的 UI 設計

上面的習題中,因為使用了 myform 的頂層表單 id,因此許多的單選、文字輸入框就可以直接透過 myform 的取得。 如果今日你只想要取出某個元素,並不要依附在頂層表單時,例如單純想要取得單選 radio 的 input 狀態時 , 也能透過類似 mysel = document.getElementsByName('sel') 來取得陣列值喔!而這種單選的陣列,可以透過 checked = {true|flase} 來抓取數值的。

4.3: 使用 switch 進行條件判斷

透過 if 的協助,我們可以判斷很多不同的狀態,真是萬用的功能。不過,如果我們的判斷式其實只有一個變數或者是簡單的邏輯資訊, 那似乎可以透過數值切換 (switch) 的語法功能來處理,讓整體程式看起來更簡單。switch 的語法有點像這樣:

switch (變數或狀態) {
case "數值或字串-1" :
	程式碼...
	break;
case "數值或字串-2" :
	程式碼...
	break;
....
default :
	程式碼...
	break;
}

整體程式由 switch 與邏輯運算開始,然後每個『值或字串』就放在 case 與冒號 (:) 當中,在底下就接需要的程式碼。離開該段程式碼, 則輸入中斷 (break;) 離開 switch。至於最後都不在規範內的數值,則以 default (預設值) 來處理掉。

例題 4-3-1:使用 switch 取代 if 進行簡單 UI 設計
  1. 將 unit04-2-3.php 另存新檔為 unit04-3-1.php,並且在index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 將 if 的語法改為 switch 的語法來處理即可。

整個畫面與 unit04-2-3.php 的呈現結果是相同的,不過,在語法的可讀性上面,會稍微好一點點,至少括號 { } 會少掉很多! 這樣閱讀起來會稍微好一些。不過也要同時注意, case 後面接的資料,應該只能是字串或整數會比較好!

4.4: 數值函數的亂數與整數應用

很多時候網頁上面可能會需要『隨機產生某些東西』的情境,這些情境就得要使用所謂的亂數來處理。 JavaScript 提供了一個數學函數,稱為 Math (注意 M 為大寫),這個 Math 函數的 .random() 就可以取得一個 0~0.9999... 之間的數值, 這就是亂數!如果想要取得一個 0~5 之間的亂數,就得要:

var myrand = Math.random() * 5;

不過你要注意的是, random() 給的是浮點數,並不是整數喔!如果需要整數,可以透過數值的 .floor() 來進行整數的『無條件捨去』法! 基本上, Math 提供的小數進位法有底下基本的三種:

Math.floor(value)    // 無條件捨去
Math.round(value)    // 四捨五入法
Math.ceil(value)     // 無條件進位

一般來說,如果是需要整數的亂數,通常使用的就是無條件捨去法 (.floor()) 來處理的!例如,我們要取得 1~6 之間的 6 個整數, 不能只是 Math.random() * 6 然後取取無條件捨去,因為這樣會變成 0~5 之間...所以才需要 +1 喔!

例題 4-4-1:使用亂數擲骰子,並與用戶比較大小
  1. 建立新檔為 unit04-4-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 使用 這個檔案 的內容貼上 unit04-4-1.php 當中,並且先查看應用一下該網頁。
  3. 設計 pcgo() 函數:
    • 這個函數的目的是要取得三個骰子的亂數,所以,先設定 pcform 這個變數來取得 pcform 這個表單元素
    • 使用 pcform.pc1.value = Math.floor(Math.random()*6)+1; 取得第一個骰子的值
    • 繼續將後續 pc2, pc3 的骰子也放上去。
  4. 設計 onload 功能:這個 pcgo() 必須亦按下按鈕才能夠進行,實在有點怪。我們讓整個網頁載入完成之後就主動執行這個函數, 可以在 <body > 裡面增加『 onload='pcgo()' 』,就可以在網頁開啟完畢後,立刻執行 pcgo() 了!看一下網頁會變這樣: 電腦骰出的結果
  5. 設計 mygo() 函數內容:
    • 設計 myform 變數來取得 myform 表單元素
    • 使用 myform.my1.value = Math.floor(Math.random()*6)+1; 取得骰子的值,並依序處理後續兩個骰子
    • 取得 pcform 元素,並且將 pc1, pc2, pc3 數值相加,假設為 pcnu 變數為其總和
    • 將 my1, my2, my3 數值相加,假設成為 mynu 總和結果
    • 取得 ans 元素
    • 使用 if 功能判斷 mynu 是否 (1)小於 (2)大於 (3)等於 pcnu,並給予不同的結果訊息,放置於 ans.innerHTML 當中。
兩者比較的結果
  • 簡單的 UI 設計

上面 4-4-1 例題有些地方怪怪的!電腦一開始骰下去得到結果之後,就不能改變了!那使用者反而可以多次擲骰子! 這與一般狀態好像不太一樣!平時玩擲骰子遊戲,都是莊家/閒家輪流擲骰子的,那如何輪流擲出骰子呢?其實很簡單! 讓使用者不能按按鈕就好了! input 標籤有個特別的屬性『 disabled 』,在 javascript 裡面可以設定為 true 與 false 呢! 你可以設計看看:

例題 4-4-2:加上簡單 UI 設計
  1. 將 unit04-4-1.php 另存新檔為 unit04-4-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
  2. 修改 pcgo() 函數:
    • 取得 myform 元素,並且設計 myform.myinp.disabled = false 且 pcform.myinp.disabled 為真
    • 取得 ans 元素,並將 ans 的 innerHTML 設定為空字串,結果會像底下這樣: 兩者比較的結果
  3. 修改 mygo() 函數:
    • 將剛剛 pcgo() 函數的 disabled 狀態反轉即可。
兩者比較的結果

這樣算是比較合乎使用者的一般操作行為吧!

4.5: 課後作業

  • onclick 與 onsubmit 的差異

一般來說,如果是『按下這個按鈕,只有本身想做的元件會做事,並不會將資料上傳到其他地方去』時,使用的就是 onclick 的資訊。 不過,我們填寫表單 (form) 之後,通常是會按下傳送 (submit) 的,這個 submit 預設就會將資料上傳出去,而不論你的填寫資料是否成功。 這個情況的問題是,可能我們某些輸入框寫錯或者是忘記寫,會導致某些錯誤啊!

因此,再傳送前,確認一下資料有沒有問題,當沒有問題後,接受到函數回傳值為 true 時,就開始順利上傳, 如果有任何問題,就直接將表單的上傳行為停止!這樣就比較不會讓使用者反彈!

為了處理這個問題,因此需要修改表單資料,通常修改的位置就是在 <form> 裡面喔!大概有點像這樣:

<form onsubmit='return somefunction()' />
....
</form>
  • element.focus() 的應用

承上,那如果你的 javascript 確認了某一個輸入框有問題的時候,是否能夠指引使用者到那一個輸入框去修改呢? 應該是這樣比較好吧!如果要這樣做,那就得要使用『 .focus() 』這個功能了!如果要移動到某個 id='myid' 的元素去, 就可以這樣:

document.getElementById('myid').focus();

知道了這幾個常用的資料,搭配 if 的語法,開始底下的實做練習吧!

  • 使用 這個檔案的內容 作為主要的表單資訊, 並建立 unit04-5-1.php 的檔案,同時也在 index.php 裡面增加一筆連結記錄。
  • 查看一下 unit04-5-1.php 的內容。

前處理準備好之後,開始來處理一些基礎資訊。

  • 先將 <form ...> 的內部,增加如上講的『 onsubmit='return mycheck()' 』之類的函數,請注意, mycheck() 是可變的,只是在這裡作為一個簡介而已。另外,在 input type='submit' 的按鈕中, 千千萬萬不要設定 onclick 喔!否則可能會衝突。
  • 建立檢查的函數,大致的流程有點像是這樣:
    1. 先抓取 myform 這個元素
    2. 檢查 myform.myaccount.value.length 整體輸入的字串長度是否大於等於 5,若小於 5 個字元時:
      • 使用 innerHTML 將訊息丟進 myaccountid 那個元素內
      • 將游標 focus 在 myform.myname 那個輸入框上面
      • 回傳 false 的結果。
    3. 檢查 myname 是否大於等於 3 個字元以上,若小於 3 個字元,使用與上述相同方式來回傳 false
    4. 檢查 mytel 的長度是否一定等於 11 個字元,使用的格式為 0900-123456 這樣的格式,不過在本章的環境下, 只需要檢查長度是否剛剛好為 11 個字元即可。若不是 11 個字元,則使用與上述相同的方式來回傳 false
    5. 檢查 mygender 是否沒有選擇 (就是值是空字串),若沒有選擇,則回傳沒有填寫,然後依據上述的方式回傳 false。
作業簡單示意圖 作業簡單示意圖 作業簡單示意圖 作業簡單示意圖 作業簡單示意圖