第 07 章 - 應用物件
上次更新日期 2020/10/27
在 JavaScript 裡面,很多的變數其實內容就是物件。物件在 JavaScript 上面是很好使用的元件, 例如上一章我們談到的陣列,就是一個很有用處的物件。這個陣列物件可以讓我們達成資料的個數分析、使用 forEach 進行傳值、 使用 sort 進行排序等。本章就讓我們來了解一下 JavaScript 的物件有哪些?以及如何應用到我們的網站上, 讓使用者更容易應用我們的網站資料。
學習目標:
- 了解 javascript 物件的屬性、方法 (method) 如何應用
- 以字串方法處理使用者輸入的資料轉換功能
- 了解二維陣列的宣告與使用方式
- 透過環境物件取得瀏覽器的相關資料
- 7.1: 什麼是物件、方法、屬性等,與 window 物件
- 7.2: 核心物件: Number, Math, String 等物件
- 7.3: 陣列的方法與二維陣列應用
- 7.4: 環境物件,如網址、螢幕參數、瀏覽器資料等
- 7.5: 課後作業
7.1: 什麼是物件、方法、屬性等,與 window 物件
在 JavaScript 裡面,幾乎所有的變數都是所謂的『物件』,因此,我們其實已經用了好久的『物件』了!只是大家可能不清楚什麼是物件的定義而已。 舉例來說,我們在之前的猜拳與擲骰子過程中,都會使用到亂數,而亂數前面那個 Math 就是所謂的『物件』,那 .random() 就是所謂的方法。 亦即是該物件可以被使用的方式就是了。另外,當我們使用『 var myform = document.getElementById('myform'); 』時,抓下來的那個 myform 也是物件, 該物件可以透過『 myform.style.border = 1px solid gray 』來給予 CSS 樣式的屬性與值。
Math.random() 物件.亂數取得的方法 myform.style.border = '1px solid gray'; 物件 .屬性 .屬性名 = '屬性值';
基本上,在 JavaScript 裡面,物件就是屬性、方法與事件的集合就是了!一個物件可以有多個不同的屬性與方法!例如上面的案例中, myform 這個物件除了可以進行 myform.style.border 之外,也可以透過 myform.pc1.value 之類的方式來取得其他元件的數值等, 所以,物件可以是網頁中的任何元件,我們可以透過這些物件,來達成網頁的互動功能。
基本上,在 JavaScript 裡面的物件,大概都屬於 window 物件就是了,這些 window 物件包涵第一章提到的 alert() 這樣。 一般來說,如同 document.getElementById 的模樣,最前面總得要加上 document 吧!不過,因為 window 屬於全域物件 (global object), 所以,通常我們寫 alert() 即可,不用寫 window.alert() 啦!除了 window 物件之外,其他還有許多的子物件, 這些子物件大致上又分為這幾大類:
- 核心物件:屬於 JavaScript 為了某些功能而提供的物件,例如數值功能的 Math、陣列功能的 Array、日期功能的 Date等, 都屬於核心物件。這方面的物件很多都是為了計算或者是取得某些額外的資料而設計的物件。
- 環境物件:這種環境物件可以取得使用者的瀏覽器相關資訊,包括涵蓋有轉址功能的 location、瀏覽器相關的 navigator、 螢幕相關的 screen 等。
- document 物件:其實就是透過 getElementById、getElementsByName 等等方式取得的元件,就是 document 物件。 我們前面幾個章節用超多的!還記得的吧!
- window 物件
window 物件的主要功能,就是在取得與改變使用者螢幕、瀏覽器資訊等資料,所以,了解這個物件,可以讓你控制使用者的瀏覽器視窗, 還有相關的螢幕位置功能喔! window 物件的屬性主要有底下這些:
屬性 | 相關參數說明 |
defaultStatus status | 視窗狀態列預設文字內容 視窗的狀態列文字(瀏覽器視窗左下角顯示的資訊) |
name | 視窗的名稱,還記得 <a> 有個參數 target 嘛?就是那個設定值功能,可以幫視窗命名 |
parent top self window | 類似指向 target='_parent' 那個父視窗去
類似指向 target='_top' 那個頂層框架去 類似指向 target='_self' 自己的 window 物件本身 與 self 相同 |
screenX screeY | 螢幕主要是以解析度 (水平x垂直像素) 來取得定位,而這個 screenX/screenY 就是取得/設定瀏覽器視窗左上角原點, 會出現在螢幕的 (X, Y) 座標軸上。 |
pageXOffset pageYOffset | 文件 (document) 在視窗內向右、向下捲動多少像素的意思 |
innerHeight innerWidth | 視窗內文件顯示的高度與寬度,單位為像素 |
outerHeight outerWidth | 視窗的總高度,包括工具列、捲軸、視窗邊框厚度等,所以,一般都是指定 innerHeight 或 outerHeight 其中之一即可, 不太會兩者同時指定囉。 |
closed | 判斷這個 window 物件是否關閉了?回傳 true 則代表不存在了,回傳 false 代表視窗還開著喔 |
opener | 指向開啟這個視窗本身的開啟者視窗。 |
- 建立新檔 unit07-1-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-1-1.php 裡面去,並觀察一下顯示結果
- 透過 window 物件的屬性數值取得 (使用 window.name 之類的方式),將最終的結果以清單的模樣累加到 res 元件上。
- window 物件的方法 (method)
剛剛 window 物件的參數也是可以調整的,除了直接調整之外,也可以透過底下的方法來進行部份調整的功能:
方法 | 相關參數說明 |
alert(msg) prompt(msg) confirm(msg) |
將 msg 訊息資料以彈出式視窗顯示 將 msg 的資料以彈出式視窗顯示外,提供使用者一個需要輸入的參數方塊(類似input) 將 msg 以彈出式方塊顯示,並提供確認與否的按鈕。主要回傳 true 或 false 的功能 |
moveBy(x,y) moveTo(x,y) | 以目前的位置為準,向 x,y 位置移動 以螢幕的左上角為原點,移動到 (x,y) 座標 |
resizeBy(x,y) resizeTo(x,y) | 調整視窗大小,寬度變化以 x 像素、高度變化以 y 像素變動 調整視窗大小到 x, y 大小 |
scrollBy(x,y) scrollTo(x,y) | 調整捲軸的位置,變化量為 x,y 調整捲軸的位置定位到 (x,y) |
close() | 關閉某個瀏覽器視窗的名稱 |
focus() | 聚焦在某個瀏覽器名稱上 |
open() | 以下表解釋 |
既然可以關閉視窗,那麼當然也能打開新視窗。打開新視窗的功能為 open(uri,name,feature),其中 uri 其實就是檔名, name 則是視窗的命名,feature 可以影響新視窗的位置與大小,內容包括有:
屬性 | 相關參數說明 |
copyhistory=1|0 | 是否複製原視窗的瀏覽歷程 |
directories=1|0 | 是否顯示導覽列 |
fullscreen=1|0 | 是否以全螢幕顯示 |
location=1|0 | 是否顯示網址列 |
menubar=1|0 | 是否顯示功能表 |
status=1|0 | 是否顯示狀態列 |
toolbar=1|0 | 是否工具列 |
scrollbar=1|0 | 當資料超過視窗時,是否顯示捲軸 |
resizable=1|0 | 是否可以改變視窗大小 |
height=Y | 高度為 Y 像素 |
width=X | 寬度為 X 像素 |
雖然理論上可以使用 window.resizeBy 等功能,不過,在許多新的瀏覽器上面,為了擔心整體系統控制權被 javascript 所惡意掌握, 因此,有兩個新的規則被定義在上述這些重要的改變視窗尺寸的限制:
- 只能改變由 window.open 啟用的視窗大小,其他非 window.open 打開的視窗 (例如自己啟動或者是透過 a 標籤打開的視窗或分頁), 就不能透過上述的設定修改
- 如果一個視窗上面有多個分頁存在時,該視窗的大小就不能夠被改變。
實際測試的情境下, firefox 以及 chrome 確實無法使用上述的功能變更原始的視窗尺寸屬性,但是較舊的 IE 則依舊能夠使用該功能。 基本上,瀏覽器開發商希望,只有從你的上層視窗啟動的子視窗 (window.open) 能夠被你改變之外,其他的視窗是希望保留原有尺寸屬性的。
- 建立新檔 unit07-1-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-1-2.php 裡面去,並觀察一下顯示結果
- 先在 script 裡面,新增一個名為 newwin 的變數,不用給任何值。此時, newwin 為一個全域變數 (所有的函數都可以使用、取代的變數值)
- 設計 myposition() 函數:
- 如果 netwin 是空的 (null),或者 newwin 就是自己 (window.self) 時,newwin 就設定為自己 (window.self)
- 取得 newwin.document.getElementById('pos') 元素,並將 innerHTML 的值設定為 (1)螢幕的 X, Y 位置, (2)瀏覽器視窗的寬、高像素
- 設計完畢之後,在 body 內,加上 onload 的事件,在開始就觸發,同時觀察一下網頁現狀。
- 注意,你可能需要自己修改 CSS 樣式,讓該方塊可以一直顯示在網頁的左下角處
- 設計 openwin() 函數:
- 設定 newwin = window.open(...) 的設計,開啟的 uri 為 unit07-1-2.html 這個檔名,視窗的名稱設定為 newwin,瀏覽器不需要導覽列、 不需要功能表、不需要工具列,不需要網址列,寬度為 800 像素,高度為 600 像素。
- 設計 fixedwin() 函數:
- 將 newwin 這個視窗,將瀏覽器尺寸 (resizeTo) 改為 1024x768 的寬高像素值
- 執行 myposition() 函數
- 設計 resizewin(mydir) 函數:
- 如果 mydir 是 up 時,使用 newwin.resizeBy() 功能處理,讓移動在 10,10 即 -10,-10 放大與縮小的範圍內處理。
- 執行 myposition() 函數
- 設計 gowhere(mydir) 函數:
- 如果 mydir 是 up 時,使用 newwin.moveBy(0,-10) 去改變視窗的位置。
- 同理,如果是 down, right, left 時,分別修改變動為 10 像素的位置
- 如果是 origin 時,則使用 newwin.moveTo 設定到 0,0 原點處
- 執行 myposition() 函數
- 設計 closewin() 函數:
- 先判斷,如果 newwin 有存在,且 newwin 不等於自己視窗 (window.self),且 newwin 是打開的,且 newwin.closed 是 false 的,若上述為真, 那就進行底下的兩行指令
- 使用 var res = window.confirm('訊息') 功能,取得讓使用者按下是/否的按鈕
- 當上述指令結果 res 為 true 時,才關閉視窗。
上述的案例很有趣,你可以開啟一個新的視窗,然後操縱新視窗到他要去的地方,或者是大小,也可以將它關閉,相當有趣。
7.2: 核心物件: Number, Math, String 等物件
JavaScript 運作時,會需要很多物件!包括數值資料、陣列資料、數值運算模式、字串處理方法等等,我們之前已經討論過許多這方面的物件, 不過,還是有一些小細節很適合進行網頁資料呈現的特色。
- Number 數值物件
當你宣告一個變數,該變數是數值時,那該變數就會成為一個數值物件 (Number)。數值物件有幾個有用的 method() 可以來玩一玩, 包括底下這些:
方法 | 相關參數說明 |
toExponential() | 使用科學方法,亦即 1.23E2 之類的方式顯示數值,其中,小數點的位數填入括號內 |
toFixed(num) | 設定固定 num 位數的小數點,方便顯示數據資料 |
toString() | 將數值轉為字串 |
toPrecision(num) | 將精確度轉為 num 位數 |
valueOf() | 取出數值的部份 |
對我們來說,最重要的應該就是 toFixed() 了!之前我們搞數值取固定位數小數點,總是沒有設計得很漂亮,這裡就能夠取得不錯的顯示資訊了。 至於 toString(), valueOf() 原本就是該有的應用,所以倒是還好。
- 建立新檔 unit07-2-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-1.php 裡面去,並觀察一下顯示結果
- 使用 getElementsByName 的方式,取得名為類似 myname 的變數,將 res 元件抓下來使用
- 依據下圖的說明,個別處理可能的數值轉換方式。
上頭只是提供一個簡單的展示方式,所以還是拿天文單位來說明而已。
- String 字串物件
字串的應用其實很重要,尤其是在正規表示法的部份,正規表示法的部份我們會獨立出一個章節來討論,這裡單純來討論一下相關的字串應用。 在 JavaScript 裡面,假設有一段文字,這段文字每個字元都有個索引 (index),所謂的索引,其實就是這個字串的第幾個字元的概念而已。
String: JavaScript is a GOOD Language.. index: 0123456789012345678901234567890 | | | |
如上所示,一段文字當中共有 31 個字元,編號則是從 0 開始編號到 30 號,所以,索引 0 為 'J' 這個字元,索引 11 為 'i' 這個字元的意思。 而 String 常見的 method 有底下這些:
- 假設字串的變數名稱為 str,且內容就是上表的 JavaScript... 那段文字
方法 | 相關參數說明 |
str.charAt(index) | 傳回第 index 個索引位置的字元,例如 str.charAt(0) 會傳回 J |
str.charCodeAt(index) | 傳回第 index 個索引位置的『字元編碼 ASCII 號碼』,例如 str.charCodeAt(0) 會傳回 74,關於 ASCII 的轉換,請看文末參考資料 |
str.indexOf(key,start) | 從 start 位置處開始找 key 這個關鍵字,若找不到回傳 -1,若找到,回傳第一個找到的索引值。例如 str.indexOf('is') 時,會回傳索引號碼 11, 若為 str.indexOf('script') 會回傳 -1 (因為沒有這個關鍵字) |
str.lastIndexOf(key) | 尋找 key 這個關鍵字,找出最後一個關鍵字的索引值。indexOf 是列出第 1 個, lastIndexOf 列出最後一個。 例如 str.lastIndexOf('a') 會回傳 26 一樣 |
str.match(key) | 在字串中尋找 key 關鍵字,找到回傳字串,找不到回傳 null,例如 str.match('Java') 回傳 Java,若 str.match('java') 則回傳 null |
str.concat(str2) | 其實,就相當於 str + str2 而已,str 並不會被改變 |
str.replace(old,new) | 將 str 字串內,找到 old 字串,修改為 new 字串。如 str.replace('Java','My cool ') |
str.split(char) | 以 char 為分隔,將字串分割成為一個陣列。例如 str.split(' ') 時,會切成 5 個值。 |
str.substr(index,length) | 從第 index 處,取出 length 個字元,例如 str.substr(16,4) 會回傳 GOOD |
str.substring(ind1,ind2) | 列出第 ind1 到第 ind2 索引所在的字元,例如 str.substring(0,9) 會列出 JavaScript |
str.toLowerCase() | 全部變小寫 |
str.toUpperCase() | 全部變大寫 |
- 建立新檔 unit07-2-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-2.php 裡面去,並觀察一下顯示結果
- 自行加入所需變數來處理成為底下的模樣
上面的測試主要在讓你了解什麼是字串的應用而已。現在來想一想,如果要讓使用者單純只能輸入大寫英文、數字與底線時, 你可以怎麼做呢?基本上,可以這樣想:
- 使用者輸入資料後,立刻使用 toUpperCase() ,讓字串內容立刻全部變成大寫字元
- 然後查看該新字元的 ASCII 字碼,可以使用 charCodeAt(str.length-1) 抓出最後的那個字元
- 判斷該字元是否在 48~57 (數字) 以及 65~90 (A-z) 或者等於 95 (_),若是,就直接將轉換過的資料回傳回 value 取代
- 承上,如果不是在該段資料,那就使用 substring(0,str.length-1) 刪除最後一個字元即可。
- 建立新檔 unit07-2-3.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-3.php 裡面去,並觀察一下顯示結果
- 開始設計 gogo() 函數的內容:
- 擷取 myinp 這個元素的控制權,可以設定變數 myinp 來處理
- 設計 myword 變數,內容為 myinp.value
- 將 myword 變成大寫字元
- 開始判斷,如果 myword 的長度大於 0 (就是有資料時),就開始進行底下的測試:
- 設計變數 check ,內容為最後一個字元的 ASCII 字碼
- 以上面的說明 (數值、大寫、底線) 來設計 if 效果,結果呈現如下:
- 符合結果,將 myinp.value 以 myword 取代
- 不符結果就刪除輸入,將 myinp.value 以 substring(0,長度 -1) 取代
這個過程可以讓使用者操作上比較開心一些吧!至少輸入的資料就一定會是正確的!
- Math 數學物件
我們前面已經用了許多的數學物件,最常用 Math.random() 這個方法了。事實上, Math 也提供了不少的屬性,不過,大部分都是用在真的數學運算上! 包括底下這些資料:
屬性 | 相關參數說明 |
Math.E | 自然數, e = 2.718281828459045 |
Math.LN2 | 使用 e 為底,取 2 的對數,意即是 ln2 |
Math.LN10 | 同上,取 10 的對數,意即是 ln10 |
Math.PI | 就是圓周率 π |
Math.SQRT2 | 取 2 的平方根 |
- 建立新檔 unit07-2-4.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-4.php 裡面去,並觀察一下顯示結果
- 將上述的資料當中,有效的小數點位數取到第 3 位即可。
至於數學 Math 物件可以使用的方法 (method) 大概有底下這些:
方法 | 相關參數說明 |
Math.abs(num) | 回傳 num 的絕對值 |
Math.cos(num) | 回傳 num 的餘弦函數,num 為弧度不是角度,其中 360° = 2π弧度,所以 1 弧度 = 180/π° = 57.2958° |
Math.sin(num) | 回傳 num 的正弦函數,num 是弧度不是角度 |
Math.tan(num) | 回傳 num 的正切函數,num 是弧度不是角度 |
Math.acos(num) | 回傳 num 的反餘弦函數,num 為弧度不是角度 |
Math.asin(num) | 回傳 num 的反正弦函數,num 是弧度不是角度 |
Math.atan(num) | 回傳 num 的反正切函數,num 是弧度不是角度 |
Math.ceil(num) Math.round(num) Math.floor(num) | 對 num 無條件進入法取整數 對 num 四捨五入取整數 對 num 無條件捨去法取整數 |
Math.exp(num) | 就是 enum |
Math.log(num) | 就是 ln(num) |
Math.pow(n1,n2) | 就是 n1n2 |
Math.sqrt(num) | 就是 num0.5,對 num 開根號的意思 |
Math.max(n1,n2) Math.min(n1,n2) | 回傳兩者間的較大值 回傳兩者間的較小值 |
Math.random() | 回傳 0~0.99999 之間的浮點數 |
基本上,都是數值運算!你可能很難用到~不過,有時候還是需要用一下...例如計算成績的時候:
- 建立新檔 unit07-2-5.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-5.php 裡面去,並觀察一下顯示結果
- 先將 myres 陣列進行排序 (sort)
- 宣告兩個空陣列,假設為 mynew1, mynew2 好了,預計作為(開根號*10)與 (成績/2+50) 的計算
- 進入 for 迴圈,迴圈為 0 到 myres 的個數,進行:
- 讓 mynew1[i] 成 myres[i] 的開根號 * 10 ,且取小數點 2 位數
- 同上,讓 mynew2[i] 變成 myres[i] 的 /2+50 的成績,一樣取小數點兩位數
- 使用清單的格式,分別定義 msg1, msg2, msg3 的原始、根號、除以2的成績對應
- 最終將上述的結果輸出到 raw, new1, new2 的 ID 方塊中。
學生考試完畢就完畢,沒什麼大不了。老師卻要考慮到學生的成績、出席率、態度、作業繳交情況、課堂討論狀態等, 啊!打成績真的好麻煩啊~~
- error 物件
某些時刻,我們要進行一個『可能會出問題』的程式碼時,或許會使用到 javascript 的 errror 物件功能! 這個 error 可以幫我們將 javascript 偵測到的錯誤顯示出來,在許多 API 當中,是很有用的工具。常見的 error 物件語法如下:
try { 要執行的程式語法放置處; } catch (自動物件變數) { 這裡放置出問題時,該進行什麼動作; 也就是說,沒問題時,這裡的資訊不會顯示喔! } finally { 可以用來處理錯誤訊息,或者是清除錯誤訊息,是一定會執行的區塊處; 通常也能省略,直接在底下用正常的語法執行後續指令即可。 }
另外, error 物件 (假設物件名稱為 myerr) 的屬性資料有:
屬性 | 說明 |
myerr.number | 回傳這個錯誤訊息的代碼 |
myerr.message | 回傳這個錯誤訊息本身 |
myerr.description | 回傳這個錯誤訊息的重要描述 |
在某些時刻,如果我們需要進行數值計算時,可以讓使用者輸入程式碼,然後我們來進行處理。這個時候,可以使用 eval() 函數。 雖然很多網友說盡量少用這個函數,不過,在某些時刻, eval() 還是很簡單的工具函數。底下,我們透過 eval 函數的輔助, 來看看計算過程中,有沒有可能會出現什麼問題:
- 建立新檔 unit07-2-6.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-2-6.php 裡面去,並觀察一下顯示結果
- 處理 gogo() 函數:
- 設定 msg, res 為空字串,這兩個等等要放置到後續的展示區
- 設定 cal 為 myform.cal.value 的字串資料,注意,是字串喔!
- 建立 try 區塊,內容就設定『 res = eval(cal) 』,亦即將 cal 處理成為計算式
- 建立 catch(myerr) 區塊,分別帶入上面的三個資訊 (雖然可能沒有定義),並將錯誤資料彙整給 msg 變數
- 將 msg 與 res 分別帶入其 innerHTML 當中。
7.3: 陣列的方法與二維陣列應用
前一章講了不少的陣列應用,基本上,陣列也是個物件喔!例如我們得要找出陣列的個數,用的就是 array.length 的屬性資料。 而剛剛前一題的排序,也是用到 array.sort() 的功能。前一章談到的陣列方法有底下這些:
myarray.length // 回傳陣列長度,亦即有幾個小抽屜的意思 myarray1.concat(myarray2) // 將 myarray2 的資料累加到 myarray1 成為新的陣列 myarray.join('分隔') // 會將元素以分隔符號連在一起,方便輸出而已 myarray.push('new_content') // 在陣列的尾端加入一筆新的陣列值,亦即增加一個小抽屜 myarray.pop() // 與 .push 相反,刪除最後一筆值,亦即拿掉最後一個小抽屜 myarray.shift() // 與 .pop 相似,刪除第一筆值,亦即拿掉第一個小抽屜 myarray.slice(n1,n2) // 將 myarray 第 n1 到第 n2-1 個元素,擷取出來的意思 myarray.sort() // 將資料進行排序,從小到大排序 myarray.sort(); myarray.reverse() // 反向排序,從大到小排序 myarray.forEach( function(myvar) { alter(myvar) } ) // 將陣列內容以 myvar 為變數名稱,一個一個執行迴圈
其實還不只啦!讓我們來理解一下這些陣列的 method 怎麼用吧!假設我們目前已經有兩個陣列,分別是:
var myarray1 = [ "one", "two", "three" ]; var myarray2 = [ "four", "five", "six" ];
接下來,讓我們使用幾個簡單的例子來介紹這些方法!
var myarray3 = myarray1.concat(myarray2); # 說明:將 myarray2 加入到 myarray1 ,並且生成 myarray3 這個陣列: # 結果:myarray3 將會是 ["one","two","three","four","five","six" ] var res = myarray1.join(", "); # 說明:簡化 myarray1 的輸出,不用特別用到 forEach 的迴圈呢! # 結果:res 的內容會是 one, two, three var res = myarray1.pop(); # 說明:將 myarray1 的最後一個值,也就是 three 拿掉的意思 # 結果:myarray1 變成 ["one","two"], res 變成 three myarray1.push("seven"); # 說明:將 myarray1 最後再加上一個值的意思 # 結果:myarray1 變成 ["one","two","three","seven"] var res = myarray1.shift(); # 說明:將 myarray1 第一個元素移除 # 結果:myarray1 變成 ["two","three"], res 變成 one var myarray4 = myarray3.slice(2,5); # 說明:以剛剛建立的 myarray3 為例,共有 6 個元素,亦即 0~5 ,從 2~4 取出來的意思 # 結果:myarray4 變成 ["three","four","five"] myarray3.sort(); # 說明:將 myarray3 進行排序,如果是數值,由小排到大,如果是文字,由 a 排到 z # 結果:myarray3 變成 ["five","four","one","six","three","two"] myarray2.reverse(); # 說明:將 myarray2 的內容反向輸出,沒有排序喔!只是反向輸出而已! # 結果:myarry2 會變成 ["six","five","four"];
- 建立新檔 unit07-3-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-3-1.php 裡面去,並觀察一下顯示結果
- 建立變數名稱為 myoutput,取得的方法為使用 getElementsByName 喔!
- 依序將陣列的結果輸出到 myouptut[X].innerHTML 當中。請注意,大部分的陣列結果,都可以用 .join(",") 或 .toString 來輸出!
- 二維陣列的宣告方法
想一想,通常考試的成績有許多次,就像我們作業的成績有許多次一樣。每個同學有多個作業成績,那麼該如何設計這些成績放入陣列? 比較笨的方法是,每次作業都是一個全新的陣列,你需要幾次成績,就放幾個陣列。只是,這樣一來,就無法透過程式碼的『變數』, 讓系統自動產生陣列~每次都要自己手動處理新的陣列名稱才行,真的有點笨。
比較好的方式,應該是透過多維陣列的方法來處理!例如某學期課程的作業成績,類似這個檔案的內容,基本上,就是每個同學每一橫列共有 10 個成績,共有 31 個同學這樣。 假設我們取一個陣列名稱為 score 的話,那麼每一個成績就會是『 score[橫列][直行] 』這樣的概念! 所以 user1 的成績就會是 score[0][0], score[0][1], score[0][2]..score[0[9]。那麼問題來了, 這個陣列該如何宣告?
基本上,變數的名稱只能宣告一次,同時,陣列宣告時,只能是宣告一維陣列而已。所以,當你需要宣告多維陣列時, 不能使用『 var score = [][]; 』,這樣會失敗!只能用底下的方式來宣告:
var score = []; // 宣告一個一維陣列 for ( i=0; i<=30; i++ ) { score[i] = [] ; // 宣告成為二維陣列 score[i][0] = ...; score[i][1] = ...; ... }
你可以很簡單的發現,第二次宣告時,就不用寫上 var 了!否則反而會失敗!因為變數名稱會重複出現的緣故! 反而會將之前的宣告摧毀!那就無法有上層宣告,所以就失敗。現在,讓我們來嘗試從網頁上面取得成績後,直接匯入使用者資訊吧!
- 建立新檔 unit07-3-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 將 這個檔案的內容 加到 unit07-3-2.php 裡面去,並觀察一下顯示結果
- 優先宣告 score 這個變數為陣列 (請設定為全域變數)
- 開始設計 gogo() 函數:
- 將 myform 這個元素抓下來,並且設定成為 myform 變數
- 設計 myscore 這個變數,內容得自 myform.myscore 的值,並且需要去頭去尾的空白 (trim()) 才好。
- 先以學生為單位來切出來,共有幾個學生?使用 tmparray1 這個陣列作為原始數據每一列的內容 (其實就是以斷行 (\n) 來切割的意思)
- 進入 for 迴圈,以 i=0 為初始值,結束限制為 i<tmparray1 的長度,然後
- 設計新變數為 tmparray2 ,內容為 tmparray1[i] 的分割,使用逗號 (,) 分割之意
- 宣告 score[i] 為陣列
- 進入 for 迴圈,以 j=0 為初始值,結束限制為 j<tmparray2 的長度,然後
- score[i][j] = tmparray2[j]
- 開始將 score 輸出!我們使用兩層 for 迴圈來輸出,輸出結果應該類似『 '<td>'+score[i][j] + '</td>' 』
- 最終使用這個檔案的內容將資料加到方塊裡面去測試看看。
上面例題的內容大部分前一章已經提到了,最重要的,其實是那個 score[i] 宣告成為陣列的項目!那個相當重要喔! 初次接觸 javascript 的多維陣列時,這一點很難懂的!
7.4: 環境物件,如網址、螢幕參數、瀏覽器資料等
在客戶端的裝置、瀏覽器上面,我們還是可以取得一些基礎資訊的!先來看看怎麼取得目前這個網頁的基本資訊。
- location 物件:主要在取得目前這個頁面的基礎資訊
使用 location 的屬性有底下這些:
屬性 | 說明 |
href | 就是本網頁的詳細網址列 |
protocol | 連線協定,例如 http, https, ftp 等 |
host hostname | 主機名稱 |
port | 連線埠口,大部分為標準埠口 (80/443) |
pathname | 網頁的基本檔名 (相對網址列) |
search | 網址列攜帶的 ? 後面的東西,可以取得變數 |
hash | 網址列攜帶的 # 後面的東西,可以得到書籤 |
其實 window.location 的屬性非常多!為了簡化整體屬性的功能,我們建議可以使用 for ... in 的迴圈語法來處理!
for ( 變數名稱 in 帶有屬性資料的物件 ) { ... } // 底下是個簡單的範例 // 原本要取得網址列通訊協定需要這樣: // window.location[protocol] 會得到 http 或 https 等,,現在可以用底下的方案處理: for ( mypro in window.location ) { res = res + mypro + ":" + window.location[mypro]; }
- 建立新檔 unit07-4-1.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 以上述的語法,建立出如下的網頁:
至於常見的 location 的方法,主要有三種,不過常用的可能是 reload 與 replace 吧!
屬性 | 說明 |
reload() | 就是重新載入這個頁面 |
replace(uri) | 將 uri 載入到目前這個網頁當中 |
assign(uri) | 將 uri 設計成為 href 的內容 |
上面的 uri 其實指的就是個檔案或網頁或網址囉!方法太簡單,這裡就不多介紹了!
- 螢幕相關參數資料取得
關於螢幕的主要屬性取得有底下這些資料:
屬性 | 說明 |
screen.height | 螢幕的高度 |
screen.width | 螢幕的寬度 |
screen.availHeight | 螢幕的可用高度 (去除桌面固定的資料,例如工作列) |
screen.availWidth | 螢幕的可用寬度 (去除桌面固定的資料,例如工作列) |
screen.colorDepth | 螢幕的色彩深度,使用二位元 (224 之類的次方項目) |
- 建立新檔 unit07-4-2.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 使用單純的清單,搭配上面表格的屬性內容,將目前螢幕的資料抓取下來:
- 瀏覽器 (navigator) 所在的相關資料
你也可以取得自己瀏覽器的相關參數來顯示,包括瀏覽器製造商、版本、作業系統支援、語系等等。若想要查看詳細的資料, 可以參考例題 7-4-1 的內容:
- 建立新檔 unit07-4-3.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 以 for ( var in...) 的語法,建立出如下的網頁:
- 歷史瀏覽資料 (history 物件)
許多網頁會有前一頁、後一頁的功能,而不是直接透過瀏覽器的原生工具列,這是透過 history 物件的輔助!他相關的方法有:
方法 | 說明 |
history.back() | 回前一頁 |
history.forward() | 往下一頁 |
history.go(num) | 回到前 num 頁(num<0)或前往下 num 頁(num>0) |
- 建立新檔 unit07-4-4.php,並在 index.php 裡面加上相關的超連結,target 指向 js 視窗。
- 使用 history 物件,指向回前一頁的按鈕。
7.5: 課後作業
- 7.5.1 自動推算出假設的成績
因為我們需要設計一些實際上不存在的使用者與成績,現在,我們需要列出
- 需要的使用者人數
- 規範的成績範圍,例如 50~80 或 30~70 或 60~90 等等,就是一個成績範圍內
- 該大致成績算出來後,推算出數個平時成績。
- 平時成績的算法,為大致成績 +-10 分,這個數值也是亂數產生的。
必須要有防呆,防呆的思考方向如下:
- 學生數、最低、最高成績、平時成績,只要有任何一個非數值,就顯示錯誤,然後 return 不再執行。
- 學生數必須要在 1~100 之間,若錯誤,就 focus 到學生框,然後顯示數量不對
- 最低、最高成績這兩欄,必須要在 10~90 之間,若錯誤,就 focus 到正確的輸入框,然後顯示成績不對
- 最高成績必須要大於等於最低成績,不然就顯示錯誤,然後 focus 到最低成績框
- 平時成績次數必須要在 1~10 之間,若錯誤,就 focus 到該框,然後顯示數量不對
開始處理成績,成績處理如下:
- 第一個 for 迴圈,使用學生數來設計:
- 學生名單使用 "user" + 迴圈的變數
- 該名學生的『通常成績』計算,可以使用這個方程式 (請自己思考為什麼?)『 Math.floor(Math.random()*(最高成績-最低成績) + 最低成績)
- 進入該名學生的平時成績推測,使用 for 迴圈,使用平時成績次數設計:
- 成績誤差值可以使用這個方程式來思考『 Math.floor(Math.random()*21 - 10) 』, 這個方程式可以推算出 -10 到 10 分之間的結果,想想看為什麼。
- 紀錄成績為『通常成績』+上述誤差值
實際處理的結果會有點像底下這樣:
- 7.5.2 二維陣列增加欄位與特殊顯色
以例題 7-3-2 為依據,然後,設計出 (1)低於 60 分有特殊框線顏色 (2)最後一欄算平均, 平均若小於 60 分,則一定要加強顯示!告知老師該名學生的成績要特別注意!
- 7.5.3 分析字串,判斷特殊格式文字
類似 7.2.3 例題的應用,寫一個網頁,讓你輸入時,可以自動偵測僅能出現大小寫字元與數字,並自動轉成大寫。 傳送前 (onsubmit),會自動判斷該輸入資訊,是否符合崑山科大日間部大學四年制學生證號格式 (ex> 4070c001):
- 第 1 個字是 4
- 第 5 個字是英文 A-Z 之間
- 其他字元是 0~9 的範圍
將 onsubmit 所攜帶的函數,一定回傳為 false,就可以停止上傳了!同時也能進行檢驗。檢驗的情境如下:
- 7.5.4 瀏覽器小算盤
以這個檔案內容來設計,撰寫一個簡單的電子計算機, 有加減乘除,以及開根號、算平方的功能即可。基本的思考是這樣的:
- 針對每個按鈕名為 myclick() 的函數,按下時,會將按下的資料累加到 myio 裡面。 但是, (1)開頭不能是 * 或 /,且 (2)結尾重複非數字時,會『取代』原有的加減乘除法。 例如,按下『 2+3/- 』時,那個 - 會取代 /,因此會變成『 2+3- 』這樣。
- myclear() 會將 myio 與 mycal 的資料通通變成空字串
- myback() 會刪除 myio 的最後一個字元
- myoutput() 會開始計算。使用 eval 計算即可。計算完畢後, 結果輸出到 myio 元素,而計算式轉到 mycal 元素上。
7.6: 參考資料
- ASCII 的 wiki 對照表:https://zh.wikipedia.org/wiki/ASCII